dkist-processing-cryonirsp 1.4.14__py3-none-any.whl → 1.4.16rc1__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-cryonirsp might be problematic. Click here for more details.

Files changed (55) hide show
  1. changelog/170.feature.rst +11 -0
  2. changelog/170.misc.1.rst +2 -0
  3. changelog/170.misc.rst +3 -0
  4. changelog/174.bugfix.rst +1 -0
  5. dkist_processing_cryonirsp/codecs/__init__.py +5 -0
  6. dkist_processing_cryonirsp/codecs/fits.py +52 -0
  7. dkist_processing_cryonirsp/models/beam_boundaries.py +39 -0
  8. dkist_processing_cryonirsp/models/parameters.py +0 -1
  9. dkist_processing_cryonirsp/models/tags.py +34 -0
  10. dkist_processing_cryonirsp/parsers/cryonirsp_l0_fits_access.py +38 -2
  11. dkist_processing_cryonirsp/parsers/exposure_conditions.py +5 -3
  12. dkist_processing_cryonirsp/tasks/assemble_movie.py +2 -2
  13. dkist_processing_cryonirsp/tasks/bad_pixel_map.py +14 -9
  14. dkist_processing_cryonirsp/tasks/beam_boundaries_base.py +24 -43
  15. dkist_processing_cryonirsp/tasks/ci_beam_boundaries.py +1 -1
  16. dkist_processing_cryonirsp/tasks/ci_science.py +24 -6
  17. dkist_processing_cryonirsp/tasks/cryonirsp_base.py +0 -10
  18. dkist_processing_cryonirsp/tasks/dark.py +34 -14
  19. dkist_processing_cryonirsp/tasks/gain.py +69 -22
  20. dkist_processing_cryonirsp/tasks/instrument_polarization.py +131 -49
  21. dkist_processing_cryonirsp/tasks/l1_output_data.py +0 -1
  22. dkist_processing_cryonirsp/tasks/linearity_correction.py +4 -7
  23. dkist_processing_cryonirsp/tasks/make_movie_frames.py +5 -5
  24. dkist_processing_cryonirsp/tasks/quality_metrics.py +4 -4
  25. dkist_processing_cryonirsp/tasks/science_base.py +34 -10
  26. dkist_processing_cryonirsp/tasks/sp_beam_boundaries.py +1 -1
  27. dkist_processing_cryonirsp/tasks/sp_dispersion_axis_correction.py +14 -6
  28. dkist_processing_cryonirsp/tasks/sp_geometric.py +112 -39
  29. dkist_processing_cryonirsp/tasks/sp_science.py +53 -11
  30. dkist_processing_cryonirsp/tasks/sp_solar_gain.py +108 -29
  31. dkist_processing_cryonirsp/tests/local_trial_workflows/l0_cals_only.py +2 -10
  32. dkist_processing_cryonirsp/tests/local_trial_workflows/l0_to_l1.py +8 -11
  33. dkist_processing_cryonirsp/tests/local_trial_workflows/local_trial_helpers.py +1 -1
  34. dkist_processing_cryonirsp/tests/test_bad_pixel_maps.py +1 -2
  35. dkist_processing_cryonirsp/tests/test_ci_beam_boundaries.py +6 -5
  36. dkist_processing_cryonirsp/tests/test_ci_science.py +25 -24
  37. dkist_processing_cryonirsp/tests/test_cryo_base.py +41 -43
  38. dkist_processing_cryonirsp/tests/test_dark.py +20 -28
  39. dkist_processing_cryonirsp/tests/test_gain.py +46 -35
  40. dkist_processing_cryonirsp/tests/test_instrument_polarization.py +22 -16
  41. dkist_processing_cryonirsp/tests/test_linearity_correction.py +1 -4
  42. dkist_processing_cryonirsp/tests/test_parse.py +41 -0
  43. dkist_processing_cryonirsp/tests/test_quality.py +1 -2
  44. dkist_processing_cryonirsp/tests/test_sp_beam_boundaries.py +6 -5
  45. dkist_processing_cryonirsp/tests/test_sp_dispersion_axis_correction.py +10 -9
  46. dkist_processing_cryonirsp/tests/test_sp_geometric.py +108 -53
  47. dkist_processing_cryonirsp/tests/test_sp_science.py +49 -35
  48. dkist_processing_cryonirsp/tests/test_sp_solar.py +70 -38
  49. {dkist_processing_cryonirsp-1.4.14.dist-info → dkist_processing_cryonirsp-1.4.16rc1.dist-info}/METADATA +2 -2
  50. {dkist_processing_cryonirsp-1.4.14.dist-info → dkist_processing_cryonirsp-1.4.16rc1.dist-info}/RECORD +52 -48
  51. dkist_processing_cryonirsp/tasks/mixin/beam_access.py +0 -52
  52. dkist_processing_cryonirsp/tasks/mixin/intermediate_frame.py +0 -193
  53. dkist_processing_cryonirsp/tasks/mixin/linearized_frame.py +0 -309
  54. {dkist_processing_cryonirsp-1.4.14.dist-info → dkist_processing_cryonirsp-1.4.16rc1.dist-info}/WHEEL +0 -0
  55. {dkist_processing_cryonirsp-1.4.14.dist-info → dkist_processing_cryonirsp-1.4.16rc1.dist-info}/top_level.txt +0 -0
@@ -6,6 +6,7 @@ import pytest
6
6
  from astropy.io import fits
7
7
  from dkist_header_validator import spec122_validator
8
8
  from dkist_processing_common._util.scratch import WorkflowFileSystem
9
+ from dkist_processing_common.codecs.fits import fits_array_encoder
9
10
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
10
11
  from dkist_processing_common.tests.conftest import FakeGQLClient
11
12
 
@@ -45,24 +46,30 @@ def ci_solar_gain_calibration_task(
45
46
  param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
46
47
  assign_input_dataset_doc_to_task(task, param_class())
47
48
  # Need a beam boundary file
48
- task.intermediate_frame_write_arrays(
49
- arrays=np.array([0, intermediate_shape[0], 0, intermediate_shape[1]]),
50
- task_tag=CryonirspTag.task_beam_boundaries(),
51
- beam=1,
49
+ task.write(
50
+ data=np.array([0, intermediate_shape[0], 0, intermediate_shape[1]]),
51
+ tags=[CryonirspTag.intermediate_frame(beam=1), CryonirspTag.task_beam_boundaries()],
52
+ encoder=fits_array_encoder,
52
53
  )
53
54
  # Create fake bad pixel map
54
- task.intermediate_frame_write_arrays(
55
- arrays=np.zeros(array_shape[1:]), task_tag=CryonirspTag.task_bad_pixel_map()
55
+ task.write(
56
+ data=np.zeros(array_shape[1:]),
57
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
58
+ encoder=fits_array_encoder,
56
59
  )
57
60
  dark_signal = 3.0
58
61
  start_time = datetime.now()
59
62
  # Make intermediate dark frame
60
63
  dark_cal = np.ones(intermediate_shape) * dark_signal
61
- task.intermediate_frame_write_arrays(
62
- arrays=dark_cal,
63
- beam=1,
64
- task_tag=CryonirspTag.task_dark(),
65
- exposure_conditions=exposure_conditions,
64
+ task.write(
65
+ data=dark_cal,
66
+ tags=[
67
+ CryonirspTag.intermediate_frame(
68
+ beam=1, exposure_conditions=exposure_conditions
69
+ ),
70
+ CryonirspTag.task_dark(),
71
+ ],
72
+ encoder=fits_array_encoder,
66
73
  )
67
74
 
68
75
  solar_signal = 6.28
@@ -82,10 +89,8 @@ def ci_solar_gain_calibration_task(
82
89
 
83
90
  hdul[0].data.fill(solar_signal + dark_signal)
84
91
  tags = [
85
- CryonirspTag.linearized(),
92
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
86
93
  CryonirspTag.task_solar_gain(),
87
- CryonirspTag.frame(),
88
- CryonirspTag.exposure_conditions(exposure_conditions),
89
94
  ]
90
95
  task.write(
91
96
  data=hdul,
@@ -124,14 +129,16 @@ def lamp_calibration_task(
124
129
  param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
125
130
  assign_input_dataset_doc_to_task(task, param_class())
126
131
  # Need a beam boundary file
127
- task.intermediate_frame_write_arrays(
128
- arrays=np.array([0, intermediate_shape[0], 0, intermediate_shape[1]]),
129
- task_tag=CryonirspTag.task_beam_boundaries(),
130
- beam=1,
132
+ task.write(
133
+ data=np.array([0, intermediate_shape[0], 0, intermediate_shape[1]]),
134
+ tags=[CryonirspTag.intermediate_frame(beam=1), CryonirspTag.task_beam_boundaries()],
135
+ encoder=fits_array_encoder,
131
136
  )
132
137
  # Create fake bad pixel map
133
- task.intermediate_frame_write_arrays(
134
- arrays=np.zeros(array_shape[1:]), task_tag=CryonirspTag.task_bad_pixel_map()
138
+ task.write(
139
+ data=np.zeros(array_shape[1:]),
140
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
141
+ encoder=fits_array_encoder,
135
142
  )
136
143
  dark_signal = 3.0
137
144
  start_time = datetime.now()
@@ -140,17 +147,25 @@ def lamp_calibration_task(
140
147
 
141
148
  # Need a dark for each beam
142
149
  for b in range(number_of_beams):
143
- task.intermediate_frame_write_arrays(
144
- arrays=dark_cal,
145
- beam=b + 1,
146
- task_tag=CryonirspTag.task_dark(),
147
- exposure_conditions=exposure_conditions,
150
+ task.write(
151
+ data=dark_cal,
152
+ tags=[
153
+ CryonirspTag.intermediate_frame(
154
+ beam=b + 1, exposure_conditions=exposure_conditions
155
+ ),
156
+ CryonirspTag.task_dark(),
157
+ ],
158
+ encoder=fits_array_encoder,
148
159
  )
160
+
149
161
  # Create fake beam border intermediate arrays
150
- task.intermediate_frame_write_arrays(
151
- arrays=np.array([0, 10, (b * 10), 10 + (b * 10)]),
152
- task_tag=CryonirspTag.task_beam_boundaries(),
153
- beam=b + 1,
162
+ task.write(
163
+ data=np.array([0, 10, (b * 10), 10 + (b * 10)]),
164
+ tags=[
165
+ CryonirspTag.intermediate_frame(beam=b + 1),
166
+ CryonirspTag.task_beam_boundaries(),
167
+ ],
168
+ encoder=fits_array_encoder,
154
169
  )
155
170
 
156
171
  # does this need to be in the beam loop as well?
@@ -173,10 +188,8 @@ def lamp_calibration_task(
173
188
  hdul[0].data.fill(1.1)
174
189
  tags = [
175
190
  CryonirspTag.beam(b + 1),
176
- CryonirspTag.linearized(),
177
191
  CryonirspTag.task_lamp_gain(),
178
- CryonirspTag.frame(),
179
- CryonirspTag.exposure_conditions(exposure_conditions),
192
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
180
193
  ]
181
194
  task.write(
182
195
  data=hdul,
@@ -203,9 +216,7 @@ def test_ci_solar_gain_calibration_task(ci_solar_gain_calibration_task, mocker):
203
216
  # Then
204
217
  tags = [
205
218
  CryonirspTag.task_solar_gain(),
206
- CryonirspTag.intermediate(),
207
- CryonirspTag.frame(),
208
- CryonirspTag.beam(1),
219
+ CryonirspTag.intermediate_frame(beam=1),
209
220
  ]
210
221
  files = list(task.read(tags=tags))
211
222
  num_files = len(files)
@@ -7,6 +7,7 @@ import pytest
7
7
  from astropy.io import fits
8
8
  from dkist_header_validator import spec122_validator
9
9
  from dkist_processing_common._util.scratch import WorkflowFileSystem
10
+ from dkist_processing_common.codecs.fits import fits_array_encoder
10
11
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
11
12
  from dkist_processing_common.models.task_name import TaskName
12
13
  from dkist_processing_common.tests.conftest import FakeGQLClient
@@ -87,9 +88,7 @@ def _create_polcal_dark_or_gain_array(
87
88
  CryonirspTag.task_polcal(),
88
89
  CryonirspTag.modstate(m),
89
90
  CryonirspTag.cs_step(cs_step),
90
- CryonirspTag.linearized(),
91
- CryonirspTag.frame(),
92
- CryonirspTag.exposure_conditions(exposure_conditions),
91
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
93
92
  ],
94
93
  encoder=fits_hdulist_encoder,
95
94
  )
@@ -130,9 +129,7 @@ def _create_polcal_arrays(
130
129
  CryonirspTag.task_polcal(),
131
130
  CryonirspTag.modstate(modstate),
132
131
  CryonirspTag.cs_step(cs_step),
133
- CryonirspTag.linearized(),
134
- CryonirspTag.frame(),
135
- CryonirspTag.exposure_conditions(exposure_conditions),
132
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
136
133
  ],
137
134
  encoder=fits_hdulist_encoder,
138
135
  )
@@ -189,13 +186,17 @@ def ci_instrument_polarization_calibration_task(
189
186
  )
190
187
 
191
188
  # Create beam border intermediate array that is consistent with a single pixel array
192
- task.intermediate_frame_write_arrays(
193
- arrays=np.array([0, 1, 0, 1]), task_tag=CryonirspTag.task_beam_boundaries(), beam=1
189
+ task.write(
190
+ data=np.array([0, 1, 0, 1]),
191
+ tags=[CryonirspTag.intermediate_frame(beam=1), CryonirspTag.task_beam_boundaries()],
192
+ encoder=fits_array_encoder,
194
193
  )
195
194
 
196
195
  # Create fake bad pixel map
197
- task.intermediate_frame_write_arrays(
198
- arrays=np.zeros((1, 1)), task_tag=CryonirspTag.task_bad_pixel_map()
196
+ task.write(
197
+ data=np.zeros((1, 1)),
198
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
199
+ encoder=fits_array_encoder,
199
200
  )
200
201
 
201
202
  start_time = datetime.now()
@@ -305,15 +306,20 @@ def sp_instrument_polarization_calibration_task(
305
306
 
306
307
  # Create beam border intermediate arrays that are consistent with a single pixel array
307
308
  for beam in range(1, num_beams + 1):
308
- task.intermediate_frame_write_arrays(
309
- arrays=np.array([0, 1, 0, 1]),
310
- task_tag=CryonirspTag.task_beam_boundaries(),
311
- beam=beam,
309
+ task.write(
310
+ data=np.array([0, 1, 0, 1]),
311
+ tags=[
312
+ CryonirspTag.intermediate_frame(beam=beam),
313
+ CryonirspTag.task_beam_boundaries(),
314
+ ],
315
+ encoder=fits_array_encoder,
312
316
  )
313
317
 
314
318
  # Create fake bad pixel map
315
- task.intermediate_frame_write_arrays(
316
- arrays=np.zeros((1, 1)), task_tag=CryonirspTag.task_bad_pixel_map()
319
+ task.write(
320
+ data=np.zeros((1, 1)),
321
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
322
+ encoder=fits_array_encoder,
317
323
  )
318
324
 
319
325
  start_time = datetime.now()
@@ -166,10 +166,7 @@ def test_linearity_correction(
166
166
  # When
167
167
  task()
168
168
  # Then
169
- tags = [
170
- CryonirspTag.linearized(),
171
- CryonirspTag.frame(),
172
- ]
169
+ tags = CryonirspTag.linearized_frame()
173
170
  # We used a perfect linear ramp from 0 to 90, where the ramp value is equal to the exposure time in ms
174
171
  # The algorithm normalizes the linearized frame by the exposure time in seconds, so the expected value is:
175
172
  # 90 / (90 / 1000) = 1000 / attenuation, where attenuation is the multiplicative attenuation due to the
@@ -1504,3 +1504,44 @@ def test_missing_lamp_gain_frames(parse_linearized_task, arm_id):
1504
1504
 
1505
1505
  with pytest.raises(ValueError, match="lamp_gain frames not found."):
1506
1506
  task()
1507
+
1508
+
1509
+ @pytest.mark.parametrize("arm_id", ["CI"])
1510
+ def test_wrong_exposure_time_lamp_gain_dark(parse_linearized_task, arm_id):
1511
+ """
1512
+ Given: lamp gain frames with a different exposure time than the dark frames
1513
+ When: parsing data where the lamp gain has no matching exposure time
1514
+ Then: everything is fine because CRYO-CI ignores lamp gains
1515
+ """
1516
+ task = parse_linearized_task
1517
+ lin_tag = [CryonirspTag.linearized()]
1518
+ solar_gain_exposure_condition = ExposureConditions(
1519
+ 10.0, AllowableOpticalDensityFilterNames.OPEN.value
1520
+ )
1521
+ write_solar_gain_frames_to_task(
1522
+ task,
1523
+ tags=lin_tag,
1524
+ exposure_condition=solar_gain_exposure_condition,
1525
+ num_modstates=1,
1526
+ )
1527
+ lamp_gain_exposure_condition = ExposureConditions(
1528
+ 1000.0, AllowableOpticalDensityFilterNames.OPEN.value
1529
+ )
1530
+ write_lamp_gain_frames_to_task(
1531
+ task,
1532
+ tags=lin_tag,
1533
+ exposure_condition=lamp_gain_exposure_condition,
1534
+ num_modstates=1,
1535
+ )
1536
+ dark_exp_condition = ExposureConditions(10.0, AllowableOpticalDensityFilterNames.OPEN.value)
1537
+ write_dark_frames_to_task(task, exposure_condition=dark_exp_condition, tags=lin_tag)
1538
+
1539
+ task()
1540
+
1541
+ assert task.constants._db_dict["DARK_FRAME_EXPOSURE_CONDITIONS_LIST"] == [[10.0, "OPEN"]]
1542
+ assert task.constants._db_dict["SOLAR_GAIN_EXPOSURE_CONDITIONS_LIST"] == [[10.0, "OPEN"]]
1543
+ assert task.constants._db_dict[
1544
+ "CI_NON_DARK_AND_NON_POLCAL_AND_NON_LAMP_GAIN_TASK_EXPOSURE_CONDITIONS_LIST"
1545
+ ] == [[10.0, "OPEN"]]
1546
+ with pytest.raises(KeyError):
1547
+ assert task.constants._db_dict["LAMP_GAIN_EXPOSURE_CONDITIONS_LIST"]
@@ -69,8 +69,7 @@ def write_l0_task_frames_to_task(num_modstates, dataset_task_types):
69
69
  data=data,
70
70
  header=header,
71
71
  tags=[
72
- CryonirspTag.linearized(),
73
- CryonirspTag.frame(),
72
+ CryonirspTag.linearized_frame(),
74
73
  CryonirspTag.task(task_type),
75
74
  CryonirspTag.modstate(modstate),
76
75
  ],
@@ -5,6 +5,7 @@ import pytest
5
5
  from astropy.io import fits
6
6
  from dkist_header_validator import spec122_validator
7
7
  from dkist_processing_common._util.scratch import WorkflowFileSystem
8
+ from dkist_processing_common.codecs.fits import fits_array_encoder
8
9
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
9
10
  from dkist_processing_common.tests.conftest import FakeGQLClient
10
11
 
@@ -40,9 +41,10 @@ def compute_beam_boundaries_task(
40
41
  param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
41
42
  assign_input_dataset_doc_to_task(task, param_class())
42
43
  # Create fake bad pixel map
43
- task.intermediate_frame_write_arrays(
44
- arrays=np.zeros(array_shape[1:]),
45
- task_tag=CryonirspTag.task_bad_pixel_map(),
44
+ task.write(
45
+ data=np.zeros(array_shape[1:]),
46
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
47
+ encoder=fits_array_encoder,
46
48
  )
47
49
  start_time = datetime.now()
48
50
  ds = CryonirspHeadersValidSPSolarGainFrames(
@@ -73,9 +75,8 @@ def compute_beam_boundaries_task(
73
75
  task.write(
74
76
  data=hdul,
75
77
  tags=[
76
- CryonirspTag.linearized(),
78
+ CryonirspTag.linearized_frame(),
77
79
  CryonirspTag.task_solar_gain(),
78
- CryonirspTag.frame(),
79
80
  ],
80
81
  encoder=fits_hdulist_encoder,
81
82
  )
@@ -7,6 +7,7 @@ from astropy.io import fits
7
7
  from dkist_header_validator import spec122_validator
8
8
  from dkist_processing_common._util.scratch import WorkflowFileSystem
9
9
  from dkist_processing_common.codecs.asdf import asdf_decoder
10
+ from dkist_processing_common.codecs.fits import fits_array_encoder
10
11
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
11
12
  from dkist_processing_common.tests.conftest import FakeGQLClient
12
13
 
@@ -65,8 +66,7 @@ def sp_dispersion_axis_correction_task(
65
66
  task.write(
66
67
  data=char_spec_hdul,
67
68
  tags=[
68
- CryonirspTag.intermediate(),
69
- CryonirspTag.frame(),
69
+ CryonirspTag.intermediate_frame(beam=beam),
70
70
  CryonirspTag.task_characteristic_spectra(),
71
71
  CryonirspTag.beam(beam),
72
72
  ],
@@ -74,10 +74,13 @@ def sp_dispersion_axis_correction_task(
74
74
  )
75
75
 
76
76
  # And a beam border intermediate array
77
- task.intermediate_frame_write_arrays(
78
- arrays=np.array([0, 30, ((beam - 1) * 30), (30 + (beam - 1) * 30)]),
79
- task_tag=CryonirspTag.task_beam_boundaries(),
80
- beam=beam,
77
+ task.write(
78
+ data=np.array([0, 30, ((beam - 1) * 30), (30 + (beam - 1) * 30)]),
79
+ tags=[
80
+ CryonirspTag.intermediate_frame(beam=beam),
81
+ CryonirspTag.task_beam_boundaries(),
82
+ ],
83
+ encoder=fits_array_encoder,
81
84
  )
82
85
 
83
86
  # Create fake linearized solar gain array with headers
@@ -99,10 +102,8 @@ def sp_dispersion_axis_correction_task(
99
102
  task.write(
100
103
  data=hdul,
101
104
  tags=[
102
- CryonirspTag.linearized(),
103
- CryonirspTag.frame(),
105
+ CryonirspTag.linearized_frame(beam=beam),
104
106
  CryonirspTag.task_solar_gain(),
105
- CryonirspTag.beam(beam),
106
107
  ],
107
108
  encoder=fits_hdulist_encoder,
108
109
  )
@@ -3,10 +3,12 @@ import json
3
3
  import numpy as np
4
4
  import pytest
5
5
  from dkist_processing_common._util.scratch import WorkflowFileSystem
6
+ from dkist_processing_common.codecs.fits import fits_array_encoder
6
7
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
7
8
  from dkist_processing_common.tests.conftest import FakeGQLClient
8
9
  from dkist_processing_math import transform
9
10
 
11
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
10
12
  from dkist_processing_cryonirsp.models.exposure_conditions import AllowableOpticalDensityFilterNames
11
13
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
12
14
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
@@ -59,32 +61,42 @@ def geometric_calibration_task_that_completes(
59
61
 
60
62
  # Create the intermediate frames needed
61
63
  # Create fake bad pixel map
62
- task.intermediate_frame_write_arrays(
63
- arrays=np.zeros(data_shape_raw),
64
- task_tag=CryonirspTag.task_bad_pixel_map(),
64
+ task.write(
65
+ data=np.zeros(data_shape_raw),
66
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
67
+ encoder=fits_array_encoder,
65
68
  )
69
+
66
70
  for beam in range(1, number_of_beams + 1):
67
71
  dark_cal = np.ones(data_shape_int) * 3.0
68
- task.intermediate_frame_write_arrays(
69
- arrays=dark_cal,
70
- beam=beam,
71
- task_tag=CryonirspTag.task_dark(),
72
- exposure_conditions=exposure_conditions,
72
+ task.write(
73
+ data=dark_cal,
74
+ tags=[
75
+ CryonirspTag.intermediate_frame(
76
+ beam=beam, exposure_conditions=exposure_conditions
77
+ ),
78
+ CryonirspTag.task_dark(),
79
+ ],
80
+ encoder=fits_array_encoder,
73
81
  )
74
82
 
75
83
  # Need a lamp for each beam
76
84
  lamp_gain = np.ones(data_shape_int)
77
- task.intermediate_frame_write_arrays(
78
- arrays=lamp_gain,
79
- beam=beam,
80
- task_tag=CryonirspTag.task_lamp_gain(),
81
- exposure_conditions=exposure_conditions,
85
+ task.write(
86
+ data=lamp_gain,
87
+ tags=[
88
+ CryonirspTag.intermediate_frame(
89
+ beam=beam, exposure_conditions=exposure_conditions
90
+ ),
91
+ CryonirspTag.task_lamp_gain(),
92
+ ],
93
+ encoder=fits_array_encoder,
82
94
  )
83
95
 
84
96
  # And a beam border intermediate array
85
97
  border = data_shape_raw[1] // 2
86
- task.intermediate_frame_write_arrays(
87
- arrays=np.array(
98
+ task.write(
99
+ data=np.array(
88
100
  [
89
101
  0,
90
102
  data_shape_int[0],
@@ -92,8 +104,11 @@ def geometric_calibration_task_that_completes(
92
104
  (border + (beam - 1) * border),
93
105
  ]
94
106
  ),
95
- task_tag=CryonirspTag.task_beam_boundaries(),
96
- beam=beam,
107
+ tags=[
108
+ CryonirspTag.intermediate_frame(beam=beam),
109
+ CryonirspTag.task_beam_boundaries(),
110
+ ],
111
+ encoder=fits_array_encoder,
97
112
  )
98
113
 
99
114
  # Create the raw data, which is based on two beams per frame
@@ -133,11 +148,10 @@ def geometric_calibration_task_that_completes(
133
148
  task.write(
134
149
  data=solar_hdul,
135
150
  tags=[
136
- CryonirspTag.linearized(),
151
+ CryonirspTag.linearized_frame(
152
+ beam=beam, exposure_conditions=exposure_conditions
153
+ ),
137
154
  CryonirspTag.task_solar_gain(),
138
- CryonirspTag.frame(),
139
- CryonirspTag.beam(beam),
140
- CryonirspTag.exposure_conditions(exposure_conditions),
141
155
  ],
142
156
  encoder=fits_hdulist_encoder,
143
157
  )
@@ -179,32 +193,41 @@ def geometric_calibration_task_with_simple_raw_data(
179
193
 
180
194
  # Create the intermediate frames needed
181
195
  # Create a fake bad pixel map
182
- task.intermediate_frame_write_arrays(
183
- arrays=np.zeros(data_shape_raw),
184
- task_tag=CryonirspTag.task_bad_pixel_map(),
196
+ task.write(
197
+ data=np.zeros(data_shape_raw),
198
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
199
+ encoder=fits_array_encoder,
185
200
  )
186
201
  for beam in range(1, number_of_beams + 1):
187
202
  dark_cal = np.ones(data_shape_int) * 3.0
188
- task.intermediate_frame_write_arrays(
189
- arrays=dark_cal,
190
- beam=beam,
191
- task_tag=CryonirspTag.task_dark(),
192
- exposure_conditions=exposure_conditions,
203
+ task.write(
204
+ data=dark_cal,
205
+ tags=[
206
+ CryonirspTag.intermediate_frame(
207
+ beam=beam, exposure_conditions=exposure_conditions
208
+ ),
209
+ CryonirspTag.task_dark(),
210
+ ],
211
+ encoder=fits_array_encoder,
193
212
  )
194
213
 
195
214
  # Need a lamp for each beam
196
215
  lamp_gain = np.ones(data_shape_int)
197
- task.intermediate_frame_write_arrays(
198
- arrays=lamp_gain,
199
- beam=beam,
200
- task_tag=CryonirspTag.task_lamp_gain(),
201
- exposure_conditions=exposure_conditions,
216
+ task.write(
217
+ data=lamp_gain,
218
+ tags=[
219
+ CryonirspTag.intermediate_frame(
220
+ beam=beam, exposure_conditions=exposure_conditions
221
+ ),
222
+ CryonirspTag.task_lamp_gain(),
223
+ ],
224
+ encoder=fits_array_encoder,
202
225
  )
203
226
 
204
227
  # And a beam border intermediate array
205
228
  border = data_shape_raw[1] // 2
206
- task.intermediate_frame_write_arrays(
207
- arrays=np.array(
229
+ task.write(
230
+ data=np.array(
208
231
  [
209
232
  0,
210
233
  data_shape_int[0],
@@ -212,18 +235,26 @@ def geometric_calibration_task_with_simple_raw_data(
212
235
  (border + (beam - 1) * border),
213
236
  ]
214
237
  ),
215
- task_tag=CryonirspTag.task_beam_boundaries(),
216
- beam=beam,
238
+ tags=[
239
+ CryonirspTag.intermediate_frame(beam=beam),
240
+ CryonirspTag.task_beam_boundaries(),
241
+ ],
242
+ encoder=fits_array_encoder,
217
243
  )
218
244
 
219
245
  # Let's write a dark with the wrong exposure time, just to make sure it doesn't get used
220
- task.intermediate_frame_write_arrays(
221
- arrays=np.ones(data_shape_int) * 1e6,
222
- beam=beam,
223
- task_tag=CryonirspTag.task_dark(),
224
- exposure_conditions=ExposureConditions(
225
- exposure_time**2, AllowableOpticalDensityFilterNames.OPEN.value
226
- ),
246
+ task.write(
247
+ data=np.ones(data_shape_int) * 1e6,
248
+ tags=[
249
+ CryonirspTag.intermediate_frame(
250
+ beam=beam,
251
+ exposure_conditions=ExposureConditions(
252
+ exposure_time**2, AllowableOpticalDensityFilterNames.OPEN.value
253
+ ),
254
+ ),
255
+ CryonirspTag.task_dark(),
256
+ ],
257
+ encoder=fits_array_encoder,
227
258
  )
228
259
 
229
260
  # Create the raw data, which is based on two beams per frame
@@ -245,10 +276,8 @@ def geometric_calibration_task_with_simple_raw_data(
245
276
  task.write(
246
277
  data=solar_hdul,
247
278
  tags=[
248
- CryonirspTag.linearized(),
279
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
249
280
  CryonirspTag.task_solar_gain(),
250
- CryonirspTag.frame(),
251
- CryonirspTag.exposure_conditions(exposure_conditions),
252
281
  ],
253
282
  encoder=fits_hdulist_encoder,
254
283
  )
@@ -271,9 +300,36 @@ def test_geometric_task(geometric_calibration_task_that_completes, mocker):
271
300
  task, beam_shape = geometric_calibration_task_that_completes
272
301
  task()
273
302
  for beam in range(1, task.constants.num_beams + 1):
274
- assert type(task.intermediate_frame_load_angle(beam=beam)) is float
275
- assert task.intermediate_frame_load_spec_shift(beam=beam).shape[0] == beam_shape[0]
276
- assert task.intermediate_frame_load_state_offset(beam=beam).shape == (2,)
303
+ angle_array = next(
304
+ task.read(
305
+ tags=[
306
+ CryonirspTag.intermediate_frame(beam=beam),
307
+ CryonirspTag.task_geometric_angle(),
308
+ ],
309
+ decoder=cryo_fits_array_decoder,
310
+ )
311
+ )
312
+ assert type(float(angle_array[0])) is float
313
+ spec_shift_array = next(
314
+ task.read(
315
+ tags=[
316
+ CryonirspTag.intermediate_frame(beam=beam),
317
+ CryonirspTag.task_geometric_spectral_shifts(),
318
+ ],
319
+ decoder=cryo_fits_array_decoder,
320
+ )
321
+ )
322
+ assert spec_shift_array.shape[0] == beam_shape[0]
323
+ state_offset_array = next(
324
+ task.read(
325
+ tags=[
326
+ CryonirspTag.intermediate_frame(beam=beam),
327
+ CryonirspTag.task_geometric_offset(),
328
+ ],
329
+ decoder=cryo_fits_array_decoder,
330
+ )
331
+ )
332
+ assert state_offset_array.shape == (2,)
277
333
 
278
334
  quality_files = task.read(tags=[CryonirspTag.quality("TASK_TYPES")])
279
335
  for file in quality_files:
@@ -282,8 +338,7 @@ def test_geometric_task(geometric_calibration_task_that_completes, mocker):
282
338
  assert isinstance(data, dict)
283
339
  assert data["total_frames"] == task.scratch.count_all(
284
340
  tags=[
285
- CryonirspTag.linearized(),
286
- CryonirspTag.frame(),
341
+ CryonirspTag.linearized_frame(),
287
342
  CryonirspTag.task_solar_gain(),
288
343
  ]
289
344
  )