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
@@ -1,15 +1,20 @@
1
1
  """Cryo gain task."""
2
2
  from abc import abstractmethod
3
- from typing import Callable
4
3
 
5
4
  import numpy as np
5
+ from dkist_processing_common.codecs.fits import fits_array_encoder
6
6
  from dkist_processing_common.models.task_name import TaskName
7
7
  from dkist_processing_math.arithmetic import subtract_array_from_arrays
8
8
  from dkist_processing_math.statistics import average_numpy_arrays
9
9
  from dkist_service_configuration.logging import logger
10
10
 
11
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
12
+ from dkist_processing_cryonirsp.models.beam_boundaries import BeamBoundary
11
13
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
12
14
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
15
+ from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import (
16
+ CryonirspLinearizedFitsAccess,
17
+ )
13
18
  from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
14
19
 
15
20
  __all__ = ["LampGainCalibration", "CISolarGainCalibration"]
@@ -44,8 +49,8 @@ class GainCalibrationBase(CryonirspTaskBase):
44
49
 
45
50
  @property
46
51
  @abstractmethod
47
- def gain_array_generator(self) -> Callable:
48
- """Return the gain array generator to use based on the gain type."""
52
+ def gain_tag(self) -> CryonirspTag:
53
+ """Return the tag to use based on the gain type."""
49
54
  pass
50
55
 
51
56
  @property
@@ -78,13 +83,29 @@ class GainCalibrationBase(CryonirspTaskBase):
78
83
  with self.apm_task_step(
79
84
  f"Generate {self.gain_type} for {len(target_exposure_conditions)} exposure times"
80
85
  ):
81
- for exposure_conditions in target_exposure_conditions:
86
+ for beam in range(1, self.constants.num_beams + 1):
82
87
  # NB: By using num_beams = 1 for CI, this method works for both CI and SP
83
- for beam in range(1, self.constants.num_beams + 1):
88
+ beam_array = next(
89
+ self.read(
90
+ tags=CryonirspTag.intermediate_beam_boundaries(beam=beam),
91
+ decoder=cryo_fits_array_decoder,
92
+ )
93
+ )
94
+ beam_boundary = BeamBoundary(*beam_array)
95
+
96
+ for exposure_conditions in target_exposure_conditions:
84
97
  apm_str = f"{beam = } and {exposure_conditions = }"
85
98
  with self.apm_processing_step(f"Remove dark signal for {apm_str}"):
86
- dark_array = self.intermediate_frame_load_dark_array(
87
- beam=beam, exposure_conditions=exposure_conditions
99
+ dark_array = next(
100
+ self.read(
101
+ tags=[
102
+ CryonirspTag.intermediate_frame(
103
+ beam=beam, exposure_conditions=exposure_conditions
104
+ ),
105
+ CryonirspTag.task_dark(),
106
+ ],
107
+ decoder=cryo_fits_array_decoder,
108
+ )
88
109
  )
89
110
 
90
111
  avg_gain_array = self.compute_average_gain_array(
@@ -96,7 +117,16 @@ class GainCalibrationBase(CryonirspTaskBase):
96
117
  )
97
118
 
98
119
  with self.apm_processing_step(f"Correct bad pixels for {apm_str}"):
99
- bad_pixel_map = self.intermediate_frame_load_bad_pixel_map(beam=beam)
120
+ bad_pixel_map = next(
121
+ self.read(
122
+ tags=[
123
+ CryonirspTag.intermediate_frame(),
124
+ CryonirspTag.task_bad_pixel_map(),
125
+ ],
126
+ decoder=cryo_fits_array_decoder,
127
+ beam_boundary=beam_boundary,
128
+ )
129
+ )
100
130
  bad_pixel_corrected_array = self.corrections_correct_bad_pixels(
101
131
  dark_corrected_gain_array, bad_pixel_map
102
132
  )
@@ -110,17 +140,21 @@ class GainCalibrationBase(CryonirspTaskBase):
110
140
  with self.apm_writing_step(
111
141
  f"Writing gain array for {beam = } and {exposure_conditions = }"
112
142
  ):
113
- self.intermediate_frame_write_arrays(
114
- normalized_gain_array,
115
- beam=beam,
116
- task=self.gain_type,
143
+ self.write(
144
+ data=normalized_gain_array,
145
+ tags=[
146
+ CryonirspTag.intermediate_frame(
147
+ beam=beam,
148
+ ),
149
+ CryonirspTag.task(self.gain_type),
150
+ ],
151
+ encoder=fits_array_encoder,
117
152
  )
118
153
 
119
154
  with self.apm_processing_step("Computing and logging quality metrics"):
120
155
  no_of_raw_gain_frames: int = self.scratch.count_all(
121
156
  tags=[
122
- CryonirspTag.linearized(),
123
- CryonirspTag.frame(),
157
+ CryonirspTag.linearized_frame(),
124
158
  CryonirspTag.task(self.gain_type),
125
159
  ],
126
160
  )
@@ -149,8 +183,21 @@ class GainCalibrationBase(CryonirspTaskBase):
149
183
  -------
150
184
  np.ndarray
151
185
  """
152
- linearized_gain_arrays = self.gain_array_generator(
153
- beam=beam, exposure_conditions=exposure_conditions
186
+ beam_array = next(
187
+ self.read(
188
+ tags=CryonirspTag.intermediate_beam_boundaries(beam=beam),
189
+ decoder=cryo_fits_array_decoder,
190
+ )
191
+ )
192
+ beam_boundary = BeamBoundary(*beam_array)
193
+ tags = CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions) + [
194
+ self.gain_tag
195
+ ]
196
+ linearized_gain_arrays = self.read(
197
+ tags=tags,
198
+ decoder=cryo_fits_array_decoder,
199
+ fits_access_class=CryonirspLinearizedFitsAccess,
200
+ beam_boundary=beam_boundary,
154
201
  )
155
202
  averaged_gain_data = average_numpy_arrays(linearized_gain_arrays)
156
203
  return averaged_gain_data
@@ -205,9 +252,9 @@ class LampGainCalibration(GainCalibrationBase):
205
252
  return self.constants.lamp_gain_exposure_conditions_list
206
253
 
207
254
  @property
208
- def gain_array_generator(self) -> Callable:
209
- """Return the gain array generator to use based on the gain type."""
210
- return self.linearized_frame_lamp_gain_array_generator
255
+ def gain_tag(self) -> CryonirspTag:
256
+ """Return the tag to use based on the gain type."""
257
+ return CryonirspTag.task(self.gain_type)
211
258
 
212
259
  @property
213
260
  def normalize_gain_switch(self) -> True:
@@ -241,9 +288,9 @@ class CISolarGainCalibration(GainCalibrationBase):
241
288
  return self.constants.solar_gain_exposure_conditions_list
242
289
 
243
290
  @property
244
- def gain_array_generator(self) -> Callable:
245
- """Return the gain array generator to use based on the gain type."""
246
- return self.linearized_frame_solar_gain_array_generator
291
+ def gain_tag(self) -> CryonirspTag:
292
+ """Return the tag to use based on the gain type."""
293
+ return CryonirspTag.task(self.gain_type)
247
294
 
248
295
  @property
249
296
  def normalize_gain_switch(self) -> False:
@@ -5,6 +5,7 @@ from collections import defaultdict
5
5
 
6
6
  import numpy as np
7
7
  from astropy.io import fits
8
+ from dkist_processing_common.codecs.fits import fits_array_encoder
8
9
  from dkist_processing_common.models.task_name import TaskName
9
10
  from dkist_processing_math.arithmetic import divide_arrays_by_array
10
11
  from dkist_processing_math.arithmetic import subtract_array_from_arrays
@@ -15,9 +16,15 @@ from dkist_processing_pac.input_data.drawer import Drawer
15
16
  from dkist_processing_pac.input_data.dresser import Dresser
16
17
  from dkist_service_configuration.logging import logger
17
18
 
19
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_access_decoder
20
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
21
+ from dkist_processing_cryonirsp.models.beam_boundaries import BeamBoundary
18
22
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
19
23
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
20
24
  from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import CryonirspL0FitsAccess
25
+ from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import (
26
+ CryonirspLinearizedFitsAccess,
27
+ )
21
28
  from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
22
29
 
23
30
  __all__ = ["CIInstrumentPolarizationCalibration", "SPInstrumentPolarizationCalibration"]
@@ -106,10 +113,13 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
106
113
  )
107
114
 
108
115
  with self.apm_writing_step(f"Writing demodulation matrices for {beam = }"):
109
- self.intermediate_frame_write_arrays(
110
- demod_matrices,
111
- beam=beam,
112
- task_tag=CryonirspTag.task_demodulation_matrices(),
116
+ self.write(
117
+ data=demod_matrices,
118
+ tags=[
119
+ CryonirspTag.intermediate_frame(beam=beam),
120
+ CryonirspTag.task_demodulation_matrices(),
121
+ ],
122
+ encoder=fits_array_encoder,
113
123
  )
114
124
 
115
125
  with self.apm_processing_step("Computing and recording polcal quality metrics"):
@@ -118,8 +128,7 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
118
128
  with self.apm_processing_step("Computing and logging quality metrics"):
119
129
  no_of_raw_polcal_frames: int = self.scratch.count_all(
120
130
  tags=[
121
- CryonirspTag.linearized(),
122
- CryonirspTag.frame(),
131
+ CryonirspTag.linearized_frame(),
123
132
  CryonirspTag.task_polcal(),
124
133
  ],
125
134
  )
@@ -151,9 +160,16 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
151
160
  for exposure_conditions in self.constants.polcal_exposure_conditions_list:
152
161
  logger.info(f"Loading dark array for {exposure_conditions = } and {beam = }")
153
162
  try:
154
- dark_array = self.intermediate_frame_load_polcal_dark_array(
155
- exposure_conditions=exposure_conditions,
156
- beam=beam,
163
+ dark_array = next(
164
+ self.read(
165
+ tags=[
166
+ CryonirspTag.intermediate_frame(
167
+ beam=beam, exposure_conditions=exposure_conditions
168
+ ),
169
+ CryonirspTag.task_polcal_dark(),
170
+ ],
171
+ decoder=cryo_fits_array_decoder,
172
+ )
157
173
  )
158
174
  except StopIteration as e:
159
175
  raise ValueError(
@@ -162,8 +178,16 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
162
178
 
163
179
  logger.info(f"Loading gain array for {exposure_conditions = } and {beam = }")
164
180
  try:
165
- gain_array = self.intermediate_frame_load_polcal_gain_array(
166
- exposure_conditions=exposure_conditions, beam=beam
181
+ gain_array = next(
182
+ self.read(
183
+ tags=[
184
+ CryonirspTag.intermediate_frame(
185
+ beam=beam, exposure_conditions=exposure_conditions
186
+ ),
187
+ CryonirspTag.task_polcal_gain(),
188
+ ],
189
+ decoder=cryo_fits_array_decoder,
190
+ )
167
191
  )
168
192
  except StopIteration as e:
169
193
  raise ValueError(
@@ -218,25 +242,31 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
218
242
  apm_str = f"{beam = }, {modstate = }, {cs_step = }, and {exposure_conditions = }"
219
243
  logger.info(f"Reducing {apm_str}")
220
244
 
221
- pol_cal_headers = (
222
- obj.header
223
- for obj in self.linearized_frame_polcal_fits_access_generator(
224
- modstate=modstate,
225
- cs_step=cs_step,
226
- exposure_conditions=exposure_conditions,
227
- beam=beam,
245
+ beam_array = next(
246
+ self.read(
247
+ tags=CryonirspTag.intermediate_beam_boundaries(beam=beam),
248
+ decoder=cryo_fits_array_decoder,
228
249
  )
229
250
  )
230
- pol_cal_arrays = (
231
- obj.data
232
- for obj in self.linearized_frame_polcal_fits_access_generator(
233
- modstate=modstate,
234
- cs_step=cs_step,
235
- exposure_conditions=exposure_conditions,
236
- beam=beam,
251
+ beam_boundary = BeamBoundary(*beam_array)
252
+ polcal_tags = [
253
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
254
+ CryonirspTag.cs_step(cs_step),
255
+ CryonirspTag.modstate(modstate),
256
+ CryonirspTag.task_polcal(),
257
+ ]
258
+ polcal_list = list(
259
+ self.read(
260
+ tags=polcal_tags,
261
+ decoder=cryo_fits_access_decoder,
262
+ fits_access_class=CryonirspLinearizedFitsAccess,
263
+ beam_boundary=beam_boundary,
237
264
  )
238
265
  )
239
266
 
267
+ pol_cal_headers = (obj.header for obj in polcal_list)
268
+ pol_cal_arrays = (obj.data for obj in polcal_list)
269
+
240
270
  avg_inst_pol_cal_header = next(pol_cal_headers)
241
271
  avg_inst_pol_cal_array = average_numpy_arrays(pol_cal_arrays)
242
272
 
@@ -321,24 +351,42 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
321
351
  with self.apm_task_step(
322
352
  f"Calculating dark frames for {len(target_exposure_conditions_list)} exp times"
323
353
  ):
324
- for exposure_conditions in target_exposure_conditions_list:
325
- for beam in range(1, self.constants.num_beams + 1):
354
+ for beam in range(1, self.constants.num_beams + 1):
355
+ beam_array = next(
356
+ self.read(
357
+ tags=CryonirspTag.intermediate_beam_boundaries(beam=beam),
358
+ decoder=cryo_fits_array_decoder,
359
+ )
360
+ )
361
+ beam_boundary = BeamBoundary(*beam_array)
362
+ for exposure_conditions in target_exposure_conditions_list:
326
363
  with self.apm_processing_step(
327
364
  f"Calculating polcal dark array(s) for {exposure_conditions = } and {beam = }"
328
365
  ):
329
- linearized_dark_arrays = self.linearized_frame_polcal_dark_array_generator(
330
- exposure_conditions=exposure_conditions,
331
- beam=beam,
366
+ linearized_dark_arrays = self.read(
367
+ tags=[
368
+ CryonirspTag.linearized_frame(
369
+ exposure_conditions=exposure_conditions
370
+ ),
371
+ CryonirspTag.task_polcal_dark(),
372
+ ],
373
+ decoder=cryo_fits_array_decoder,
374
+ fits_access_class=CryonirspLinearizedFitsAccess,
375
+ beam_boundary=beam_boundary,
332
376
  )
333
377
  averaged_dark_array = average_numpy_arrays(linearized_dark_arrays)
334
378
  with self.apm_writing_step(
335
379
  f"Writing dark for {exposure_conditions = } and {beam = }"
336
380
  ):
337
- self.intermediate_frame_write_arrays(
338
- averaged_dark_array,
339
- task_tag=CryonirspTag.task_polcal_dark(),
340
- exposure_conditions=exposure_conditions,
341
- beam=beam,
381
+ self.write(
382
+ data=averaged_dark_array,
383
+ tags=[
384
+ CryonirspTag.intermediate_frame(
385
+ beam=beam, exposure_conditions=exposure_conditions
386
+ ),
387
+ CryonirspTag.task_polcal_dark(),
388
+ ],
389
+ encoder=fits_array_encoder,
342
390
  )
343
391
 
344
392
  def generate_polcal_gain_calibration(self, exposure_conditions_list: [ExposureConditions]):
@@ -346,15 +394,29 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
346
394
  with self.apm_task_step(
347
395
  f"Generate gains for {len(exposure_conditions_list)} exposure conditions"
348
396
  ):
349
- for exposure_conditions in exposure_conditions_list:
350
- for beam in range(1, self.constants.num_beams + 1):
397
+ for beam in range(1, self.constants.num_beams + 1):
398
+ beam_array = next(
399
+ self.read(
400
+ tags=CryonirspTag.intermediate_beam_boundaries(beam=beam),
401
+ decoder=cryo_fits_array_decoder,
402
+ )
403
+ )
404
+ beam_boundary = BeamBoundary(*beam_array)
405
+ for exposure_conditions in exposure_conditions_list:
351
406
  logger.info(
352
407
  f"Load polcal dark array for {exposure_conditions = } and {beam = }"
353
408
  )
354
409
  try:
355
- dark_array = self.intermediate_frame_load_polcal_dark_array(
356
- exposure_conditions=exposure_conditions,
357
- beam=beam,
410
+ dark_array = next(
411
+ self.read(
412
+ tags=[
413
+ CryonirspTag.intermediate_frame(
414
+ beam=beam, exposure_conditions=exposure_conditions
415
+ ),
416
+ CryonirspTag.task_polcal_dark(),
417
+ ],
418
+ decoder=cryo_fits_array_decoder,
419
+ )
358
420
  )
359
421
  except StopIteration as e:
360
422
  raise ValueError(
@@ -363,16 +425,32 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
363
425
  with self.apm_processing_step(
364
426
  f"Calculating polcal gain array(s) for {exposure_conditions = } and {beam = }"
365
427
  ):
366
- linearized_gain_arrays = self.linearized_frame_polcal_gain_array_generator(
367
- exposure_conditions=exposure_conditions,
368
- beam=beam,
428
+ linearized_gain_arrays = self.read(
429
+ tags=[
430
+ CryonirspTag.linearized_frame(
431
+ exposure_conditions=exposure_conditions
432
+ ),
433
+ CryonirspTag.task_polcal_gain(),
434
+ ],
435
+ decoder=cryo_fits_array_decoder,
436
+ fits_access_class=CryonirspLinearizedFitsAccess,
437
+ beam_boundary=beam_boundary,
369
438
  )
370
439
  averaged_gain_array = average_numpy_arrays(linearized_gain_arrays)
371
440
  dark_corrected_gain_array = next(
372
441
  subtract_array_from_arrays(averaged_gain_array, dark_array)
373
442
  )
374
443
 
375
- bad_pixel_map = self.intermediate_frame_load_bad_pixel_map(beam=beam)
444
+ bad_pixel_map = next(
445
+ self.read(
446
+ tags=[
447
+ CryonirspTag.intermediate_frame(),
448
+ CryonirspTag.task_bad_pixel_map(),
449
+ ],
450
+ decoder=cryo_fits_array_decoder,
451
+ beam_boundary=beam_boundary,
452
+ )
453
+ )
376
454
  bad_pixel_corrected_array = self.corrections_correct_bad_pixels(
377
455
  dark_corrected_gain_array, bad_pixel_map
378
456
  )
@@ -384,11 +462,15 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
384
462
  with self.apm_writing_step(
385
463
  f"Writing gain array for exposure time {exposure_conditions} and {beam = }"
386
464
  ):
387
- self.intermediate_frame_write_arrays(
388
- normalized_gain_array,
389
- task_tag=CryonirspTag.task_polcal_gain(),
390
- exposure_conditions=exposure_conditions,
391
- beam=beam,
465
+ self.write(
466
+ data=normalized_gain_array,
467
+ tags=[
468
+ CryonirspTag.intermediate_frame(
469
+ beam=beam, exposure_conditions=exposure_conditions
470
+ ),
471
+ CryonirspTag.task_polcal_gain(),
472
+ ],
473
+ encoder=fits_array_encoder,
392
474
  )
393
475
 
394
476
 
@@ -1,7 +1,6 @@
1
1
  """Subclasses of AssembleQualityData that cause the correct polcal metrics to build."""
2
2
  from typing import Type
3
3
 
4
- from dkist_processing_common.models.constants import ConstantsBase
5
4
  from dkist_processing_common.tasks import AssembleQualityData
6
5
 
7
6
  __all__ = ["CIAssembleQualityData", "SPAssembleQualityData"]
@@ -3,14 +3,12 @@ from dataclasses import dataclass
3
3
  from typing import Generator
4
4
 
5
5
  import numpy as np
6
- from astropy.io import fits
7
- from dkist_processing_common.codecs.fits import fits_access_decoder
8
6
  from dkist_processing_common.codecs.fits import fits_array_encoder
9
- from dkist_processing_common.codecs.fits import fits_hdulist_encoder
10
7
  from dkist_service_configuration.logging import logger
11
8
  from numba import njit
12
9
  from numba import prange
13
10
 
11
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_access_decoder
14
12
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
15
13
  from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import CryonirspRampFitsAccess
16
14
  from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
@@ -73,8 +71,7 @@ class LinearityCorrection(CryonirspTaskBase):
73
71
  )
74
72
  # Set the tags for the linearized output frame
75
73
  tags = [
76
- CryonirspTag.linearized(),
77
- CryonirspTag.frame(),
74
+ CryonirspTag.linearized_frame(),
78
75
  CryonirspTag.time_obs(time_obs),
79
76
  ]
80
77
  # The last frame in the ramp is used for the header
@@ -113,7 +110,7 @@ class LinearityCorrection(CryonirspTaskBase):
113
110
  CryonirspTag.frame(),
114
111
  CryonirspTag.time_obs(time_obs),
115
112
  ],
116
- decoder=fits_access_decoder,
113
+ decoder=cryo_fits_access_decoder,
117
114
  fits_access_class=CryonirspRampFitsAccess,
118
115
  )
119
116
  )
@@ -186,7 +183,7 @@ class LinearityCorrection(CryonirspTaskBase):
186
183
  fits_obj_list = list(
187
184
  self.read(
188
185
  tags=tags,
189
- decoder=fits_access_decoder,
186
+ decoder=cryo_fits_access_decoder,
190
187
  fits_access_class=CryonirspRampFitsAccess,
191
188
  )
192
189
  )
@@ -5,10 +5,10 @@ from abc import abstractmethod
5
5
  import numpy as np
6
6
  from astropy.io import fits
7
7
  from astropy.visualization import ZScaleInterval
8
- from dkist_processing_common.codecs.fits import fits_access_decoder
9
8
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
10
9
  from dkist_service_configuration.logging import logger
11
10
 
11
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_access_decoder
12
12
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
13
13
  from dkist_processing_cryonirsp.parsers.cryonirsp_l1_fits_access import CryonirspL1FitsAccess
14
14
  from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
@@ -73,7 +73,7 @@ class MakeCryonirspMovieFramesBase(CryonirspTaskBase, ABC):
73
73
  CryonirspTag.map_scan(map_scan),
74
74
  CryonirspTag.scan_step(scan_step),
75
75
  ],
76
- decoder=fits_access_decoder,
76
+ decoder=cryo_fits_access_decoder,
77
77
  fits_access_class=CryonirspL1FitsAccess,
78
78
  )
79
79
  )
@@ -157,7 +157,7 @@ class MakeCryonirspMovieFrames(MakeCryonirspMovieFramesBase):
157
157
  CryonirspTag.map_scan(map_scan),
158
158
  CryonirspTag.scan_step(scan_step),
159
159
  ],
160
- decoder=fits_access_decoder,
160
+ decoder=cryo_fits_access_decoder,
161
161
  fits_access_class=CryonirspL1FitsAccess,
162
162
  )
163
163
  )
@@ -260,7 +260,7 @@ class SPMakeCryonirspMovieFrames(MakeCryonirspMovieFramesBase):
260
260
  CryonirspTag.map_scan(map_scan),
261
261
  CryonirspTag.scan_step(scan_step),
262
262
  ],
263
- decoder=fits_access_decoder,
263
+ decoder=cryo_fits_access_decoder,
264
264
  fits_access_class=CryonirspL1FitsAccess,
265
265
  )
266
266
  )
@@ -286,7 +286,7 @@ class SPMakeCryonirspMovieFrames(MakeCryonirspMovieFramesBase):
286
286
  CryonirspTag.map_scan(map_scan),
287
287
  CryonirspTag.scan_step(scan_step),
288
288
  ],
289
- decoder=fits_access_decoder,
289
+ decoder=cryo_fits_access_decoder,
290
290
  fits_access_class=CryonirspL1FitsAccess,
291
291
  )
292
292
  )
@@ -6,12 +6,12 @@ from typing import Iterable
6
6
 
7
7
  import numpy as np
8
8
  from astropy.time import Time
9
- from dkist_processing_common.codecs.fits import fits_access_decoder
10
9
  from dkist_processing_common.parsers.quality import L1QualityFitsAccess
11
10
  from dkist_processing_common.tasks import QualityL0Metrics
12
11
  from dkist_processing_common.tasks.mixin.quality import QualityMixin
13
12
  from dkist_service_configuration.logging import logger
14
13
 
14
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_access_decoder
15
15
  from dkist_processing_cryonirsp.models.constants import CryonirspConstants
16
16
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
17
17
  from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
@@ -212,7 +212,7 @@ class CryonirspL1QualityMetrics(CryonirspTaskBase, QualityMixin):
212
212
  CryonirspTag.stokes(stokes_state),
213
213
  CryonirspTag.meas_num(meas_num),
214
214
  ],
215
- decoder=fits_access_decoder,
215
+ decoder=cryo_fits_access_decoder,
216
216
  fits_access_class=L1QualityFitsAccess,
217
217
  )
218
218
  )
@@ -241,7 +241,7 @@ class CryonirspL1QualityMetrics(CryonirspTaskBase, QualityMixin):
241
241
  CryonirspTag.stokes("I"),
242
242
  CryonirspTag.meas_num(meas_num),
243
243
  ],
244
- decoder=fits_access_decoder,
244
+ decoder=cryo_fits_access_decoder,
245
245
  fits_access_class=L1QualityFitsAccess,
246
246
  )
247
247
  )
@@ -258,7 +258,7 @@ class CryonirspL1QualityMetrics(CryonirspTaskBase, QualityMixin):
258
258
  tags = [CryonirspTag.calibrated(), CryonirspTag.frame(), CryonirspTag.stokes(stokes)]
259
259
  frames: Generator[L1QualityFitsAccess, None, None] = self.read(
260
260
  tags=tags,
261
- decoder=fits_access_decoder,
261
+ decoder=cryo_fits_access_decoder,
262
262
  fits_access_class=L1QualityFitsAccess,
263
263
  )
264
264
  result = _QualityData()
@@ -16,9 +16,15 @@ from dkist_processing_math.statistics import average_numpy_arrays
16
16
  from dkist_processing_pac.optics.telescope import Telescope
17
17
  from dkist_service_configuration.logging import logger
18
18
 
19
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_access_decoder
20
+ from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
21
+ from dkist_processing_cryonirsp.models.beam_boundaries import BeamBoundary
19
22
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
20
23
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
21
24
  from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import CryonirspL0FitsAccess
25
+ from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import (
26
+ CryonirspLinearizedFitsAccess,
27
+ )
22
28
  from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
23
29
 
24
30
 
@@ -76,8 +82,7 @@ class ScienceCalibrationBase(CryonirspTaskBase, ABC):
76
82
  with self.apm_processing_step("Computing and logging quality metrics"):
77
83
  no_of_raw_science_frames: int = self.scratch.count_all(
78
84
  tags=[
79
- CryonirspTag.linearized(),
80
- CryonirspTag.frame(),
85
+ CryonirspTag.linearized_frame(),
81
86
  CryonirspTag.task_observe(),
82
87
  ],
83
88
  )
@@ -143,14 +148,27 @@ class ScienceCalibrationBase(CryonirspTaskBase, ABC):
143
148
  gain_array = calibrations.solar_gain[CryonirspTag.beam(beam)]
144
149
 
145
150
  # Grab the input observe frame(s)
151
+ beam_array = next(
152
+ self.read(
153
+ tags=CryonirspTag.intermediate_beam_boundaries(beam=beam),
154
+ decoder=cryo_fits_array_decoder,
155
+ )
156
+ )
157
+ beam_boundary = BeamBoundary(*beam_array)
158
+ observe_object_tags = [
159
+ CryonirspTag.linearized_frame(exposure_conditions=exposure_conditions),
160
+ CryonirspTag.map_scan(map_scan),
161
+ CryonirspTag.scan_step(scan_step),
162
+ CryonirspTag.meas_num(meas_num),
163
+ CryonirspTag.modstate(modstate),
164
+ CryonirspTag.task_observe(),
165
+ ]
146
166
  observe_object_list = list(
147
- self.linearized_frame_observe_fits_access_generator(
148
- beam=beam,
149
- map_scan=map_scan,
150
- scan_step=scan_step,
151
- meas_num=meas_num,
152
- modstate=modstate,
153
- exposure_conditions=exposure_conditions,
167
+ self.read(
168
+ tags=observe_object_tags,
169
+ decoder=cryo_fits_access_decoder,
170
+ fits_access_class=CryonirspLinearizedFitsAccess,
171
+ beam_boundary=beam_boundary,
154
172
  )
155
173
  )
156
174
  # There can be more than 1 frame if there are sub-repeats
@@ -170,7 +188,13 @@ class ScienceCalibrationBase(CryonirspTaskBase, ABC):
170
188
  dark_corrected_array = next(subtract_array_from_arrays(avg_observe_array, dark_array))
171
189
 
172
190
  # Bad pixel correction
173
- bad_pixel_map = self.intermediate_frame_load_bad_pixel_map(beam=beam)
191
+ bad_pixel_map = next(
192
+ self.read(
193
+ tags=[CryonirspTag.intermediate_frame(), CryonirspTag.task_bad_pixel_map()],
194
+ decoder=cryo_fits_array_decoder,
195
+ beam_boundary=beam_boundary,
196
+ )
197
+ )
174
198
  bad_pixel_corrected_array = self.corrections_correct_bad_pixels(
175
199
  dark_corrected_array, bad_pixel_map
176
200
  )