dkist-processing-cryonirsp 1.4.20__py3-none-any.whl → 1.14.9rc1__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.
Files changed (95) hide show
  1. changelog/232.misc.rst +1 -0
  2. dkist_processing_cryonirsp/__init__.py +1 -0
  3. dkist_processing_cryonirsp/codecs/fits.py +1 -0
  4. dkist_processing_cryonirsp/config.py +5 -1
  5. dkist_processing_cryonirsp/models/beam_boundaries.py +1 -0
  6. dkist_processing_cryonirsp/models/constants.py +31 -30
  7. dkist_processing_cryonirsp/models/exposure_conditions.py +6 -5
  8. dkist_processing_cryonirsp/models/fits_access.py +40 -0
  9. dkist_processing_cryonirsp/models/parameters.py +14 -26
  10. dkist_processing_cryonirsp/models/tags.py +1 -0
  11. dkist_processing_cryonirsp/models/task_name.py +1 -0
  12. dkist_processing_cryonirsp/parsers/check_for_gains.py +1 -0
  13. dkist_processing_cryonirsp/parsers/cryonirsp_l0_fits_access.py +40 -47
  14. dkist_processing_cryonirsp/parsers/cryonirsp_l1_fits_access.py +1 -0
  15. dkist_processing_cryonirsp/parsers/exposure_conditions.py +14 -13
  16. dkist_processing_cryonirsp/parsers/map_repeats.py +1 -0
  17. dkist_processing_cryonirsp/parsers/measurements.py +29 -16
  18. dkist_processing_cryonirsp/parsers/modstates.py +5 -1
  19. dkist_processing_cryonirsp/parsers/optical_density_filters.py +1 -0
  20. dkist_processing_cryonirsp/parsers/polarimetric_check.py +18 -7
  21. dkist_processing_cryonirsp/parsers/scan_step.py +12 -4
  22. dkist_processing_cryonirsp/parsers/time.py +7 -7
  23. dkist_processing_cryonirsp/parsers/wavelength.py +6 -1
  24. dkist_processing_cryonirsp/tasks/__init__.py +2 -1
  25. dkist_processing_cryonirsp/tasks/assemble_movie.py +1 -0
  26. dkist_processing_cryonirsp/tasks/bad_pixel_map.py +6 -5
  27. dkist_processing_cryonirsp/tasks/beam_boundaries_base.py +12 -11
  28. dkist_processing_cryonirsp/tasks/ci_beam_boundaries.py +1 -0
  29. dkist_processing_cryonirsp/tasks/ci_science.py +1 -0
  30. dkist_processing_cryonirsp/tasks/cryonirsp_base.py +2 -3
  31. dkist_processing_cryonirsp/tasks/dark.py +5 -4
  32. dkist_processing_cryonirsp/tasks/gain.py +7 -6
  33. dkist_processing_cryonirsp/tasks/instrument_polarization.py +17 -16
  34. dkist_processing_cryonirsp/tasks/l1_output_data.py +1 -0
  35. dkist_processing_cryonirsp/tasks/linearity_correction.py +1 -0
  36. dkist_processing_cryonirsp/tasks/make_movie_frames.py +3 -2
  37. dkist_processing_cryonirsp/tasks/mixin/corrections.py +1 -0
  38. dkist_processing_cryonirsp/tasks/mixin/shift_measurements.py +9 -2
  39. dkist_processing_cryonirsp/tasks/parse.py +70 -52
  40. dkist_processing_cryonirsp/tasks/quality_metrics.py +15 -14
  41. dkist_processing_cryonirsp/tasks/science_base.py +8 -6
  42. dkist_processing_cryonirsp/tasks/sp_beam_boundaries.py +2 -1
  43. dkist_processing_cryonirsp/tasks/sp_geometric.py +11 -10
  44. dkist_processing_cryonirsp/tasks/sp_science.py +1 -0
  45. dkist_processing_cryonirsp/tasks/sp_solar_gain.py +15 -12
  46. dkist_processing_cryonirsp/tasks/sp_wavelength_calibration.py +300 -0
  47. dkist_processing_cryonirsp/tasks/write_l1.py +59 -38
  48. dkist_processing_cryonirsp/tests/conftest.py +75 -53
  49. dkist_processing_cryonirsp/tests/header_models.py +62 -11
  50. dkist_processing_cryonirsp/tests/local_trial_workflows/l0_cals_only.py +26 -46
  51. dkist_processing_cryonirsp/tests/local_trial_workflows/l0_to_l1.py +26 -47
  52. dkist_processing_cryonirsp/tests/local_trial_workflows/linearize_only.py +3 -3
  53. dkist_processing_cryonirsp/tests/local_trial_workflows/local_trial_helpers.py +57 -26
  54. dkist_processing_cryonirsp/tests/test_assemble_movie.py +4 -5
  55. dkist_processing_cryonirsp/tests/test_assemble_qualilty.py +5 -1
  56. dkist_processing_cryonirsp/tests/test_bad_pixel_maps.py +4 -5
  57. dkist_processing_cryonirsp/tests/test_ci_beam_boundaries.py +4 -5
  58. dkist_processing_cryonirsp/tests/test_ci_science.py +4 -5
  59. dkist_processing_cryonirsp/tests/test_corrections.py +5 -6
  60. dkist_processing_cryonirsp/tests/test_cryo_base.py +4 -6
  61. dkist_processing_cryonirsp/tests/test_cryo_constants.py +7 -3
  62. dkist_processing_cryonirsp/tests/test_dark.py +7 -8
  63. dkist_processing_cryonirsp/tests/test_fits_access.py +44 -0
  64. dkist_processing_cryonirsp/tests/test_gain.py +7 -8
  65. dkist_processing_cryonirsp/tests/test_instrument_polarization.py +19 -10
  66. dkist_processing_cryonirsp/tests/test_linearity_correction.py +5 -4
  67. dkist_processing_cryonirsp/tests/test_make_movie_frames.py +2 -3
  68. dkist_processing_cryonirsp/tests/test_parameters.py +23 -28
  69. dkist_processing_cryonirsp/tests/test_parse.py +48 -12
  70. dkist_processing_cryonirsp/tests/test_quality.py +2 -3
  71. dkist_processing_cryonirsp/tests/test_sp_beam_boundaries.py +5 -5
  72. dkist_processing_cryonirsp/tests/test_sp_geometric.py +5 -6
  73. dkist_processing_cryonirsp/tests/test_sp_make_movie_frames.py +2 -3
  74. dkist_processing_cryonirsp/tests/test_sp_science.py +4 -5
  75. dkist_processing_cryonirsp/tests/test_sp_solar.py +6 -5
  76. dkist_processing_cryonirsp/tests/{test_sp_dispersion_axis_correction.py → test_sp_wavelength_calibration.py} +11 -29
  77. dkist_processing_cryonirsp/tests/test_trial_create_quality_report.py +1 -1
  78. dkist_processing_cryonirsp/tests/test_workflows.py +1 -0
  79. dkist_processing_cryonirsp/tests/test_write_l1.py +29 -31
  80. dkist_processing_cryonirsp/workflows/__init__.py +1 -0
  81. dkist_processing_cryonirsp/workflows/ci_l0_processing.py +9 -5
  82. dkist_processing_cryonirsp/workflows/sp_l0_processing.py +12 -8
  83. dkist_processing_cryonirsp/workflows/trial_workflows.py +12 -11
  84. dkist_processing_cryonirsp-1.14.9rc1.dist-info/METADATA +552 -0
  85. dkist_processing_cryonirsp-1.14.9rc1.dist-info/RECORD +115 -0
  86. {dkist_processing_cryonirsp-1.4.20.dist-info → dkist_processing_cryonirsp-1.14.9rc1.dist-info}/WHEEL +1 -1
  87. docs/ci_science_calibration.rst +10 -0
  88. docs/conf.py +1 -0
  89. docs/index.rst +1 -0
  90. docs/sp_science_calibration.rst +7 -0
  91. docs/wavelength_calibration.rst +62 -0
  92. dkist_processing_cryonirsp/tasks/sp_dispersion_axis_correction.py +0 -492
  93. dkist_processing_cryonirsp-1.4.20.dist-info/METADATA +0 -452
  94. dkist_processing_cryonirsp-1.4.20.dist-info/RECORD +0 -111
  95. {dkist_processing_cryonirsp-1.4.20.dist-info → dkist_processing_cryonirsp-1.14.9rc1.dist-info}/top_level.txt +0 -0
@@ -8,7 +8,6 @@ from dkist_processing_common._util.scratch import WorkflowFileSystem
8
8
  from dkist_processing_common.codecs.fits import fits_array_encoder
9
9
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
10
10
  from dkist_processing_common.models.task_name import TaskName
11
- from dkist_processing_common.tests.conftest import FakeGQLClient
12
11
 
13
12
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
14
13
  from dkist_processing_cryonirsp.tasks.quality_metrics import CryonirspL0QualityMetrics
@@ -161,7 +160,7 @@ def test_l0_quality_task(
161
160
  assert len(files) > 0
162
161
 
163
162
 
164
- def test_l1_quality_task(cryo_l1_quality_task, mocker):
163
+ def test_l1_quality_task(cryo_l1_quality_task, mocker, fake_gql_client):
165
164
  """
166
165
  Given: A CryonirspL1QualityMetrics task
167
166
  When: Calling the task instance
@@ -169,7 +168,7 @@ def test_l1_quality_task(cryo_l1_quality_task, mocker):
169
168
  and a single noise measurement and datetime is recorded for L1 file for each Stokes Q, U, and V
170
169
  """
171
170
  mocker.patch(
172
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
171
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
173
172
  )
174
173
  # When
175
174
  task = cryo_l1_quality_task
@@ -7,12 +7,12 @@ from dkist_header_validator import spec122_validator
7
7
  from dkist_processing_common._util.scratch import WorkflowFileSystem
8
8
  from dkist_processing_common.codecs.fits import fits_array_encoder
9
9
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
10
- from dkist_processing_common.tests.conftest import FakeGQLClient
11
10
 
12
11
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
13
12
  from dkist_processing_cryonirsp.tasks.sp_beam_boundaries import SPBeamBoundariesCalibration
14
- from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
15
13
  from dkist_processing_cryonirsp.tests.conftest import CryonirspConstantsDb
14
+ from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
15
+ from dkist_processing_cryonirsp.tests.conftest import fake_gql_client
16
16
  from dkist_processing_cryonirsp.tests.conftest import generate_fits_frame
17
17
  from dkist_processing_cryonirsp.tests.header_models import CryonirspHeadersValidSPSolarGainFrames
18
18
 
@@ -38,7 +38,7 @@ def compute_beam_boundaries_task(
38
38
  task.scratch = WorkflowFileSystem(
39
39
  scratch_base_path=tmp_path, recipe_run_id=recipe_run_id
40
40
  )
41
- param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
41
+ param_class = cryonirsp_testing_parameters_factory(task)
42
42
  assign_input_dataset_doc_to_task(task, param_class())
43
43
  # Create fake bad pixel map
44
44
  task.write(
@@ -85,14 +85,14 @@ def compute_beam_boundaries_task(
85
85
  task._purge()
86
86
 
87
87
 
88
- def test_compute_beam_boundaries_task(compute_beam_boundaries_task, mocker):
88
+ def test_compute_beam_boundaries_task(compute_beam_boundaries_task, mocker, fake_gql_client):
89
89
  """
90
90
  Given: A SPBeamBoundariesCalibration task
91
91
  When: Calling the task instance with known input data
92
92
  Then: The correct beam boundary values are created and saved as intermediate files
93
93
  """
94
94
  mocker.patch(
95
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
95
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
96
96
  )
97
97
  # Given
98
98
  task, arm_id = compute_beam_boundaries_task
@@ -5,7 +5,6 @@ import pytest
5
5
  from dkist_processing_common._util.scratch import WorkflowFileSystem
6
6
  from dkist_processing_common.codecs.fits import fits_array_encoder
7
7
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
8
- from dkist_processing_common.tests.conftest import FakeGQLClient
9
8
  from dkist_processing_math import transform
10
9
 
11
10
  from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
@@ -13,8 +12,8 @@ from dkist_processing_cryonirsp.models.exposure_conditions import AllowableOptic
13
12
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
14
13
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
15
14
  from dkist_processing_cryonirsp.tasks.sp_geometric import SPGeometricCalibration
16
- from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
17
15
  from dkist_processing_cryonirsp.tests.conftest import CryonirspConstantsDb
16
+ from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
18
17
  from dkist_processing_cryonirsp.tests.conftest import generate_214_l0_fits_frame
19
18
  from dkist_processing_cryonirsp.tests.header_models import CryonirspHeadersValidSPSolarGainFrames
20
19
 
@@ -52,7 +51,7 @@ def geometric_calibration_task_that_completes(
52
51
  task.scratch = WorkflowFileSystem(
53
52
  scratch_base_path=tmp_path, recipe_run_id=recipe_run_id
54
53
  )
55
- param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
54
+ param_class = cryonirsp_testing_parameters_factory(task)
56
55
  assign_input_dataset_doc_to_task(task, param_class())
57
56
 
58
57
  task.angles = [0.0, 0.0]
@@ -188,7 +187,7 @@ def geometric_calibration_task_with_simple_raw_data(
188
187
  task.scratch = WorkflowFileSystem(
189
188
  scratch_base_path=tmp_path, recipe_run_id=recipe_run_id
190
189
  )
191
- param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
190
+ param_class = cryonirsp_testing_parameters_factory(task)
192
191
  assign_input_dataset_doc_to_task(task, param_class())
193
192
 
194
193
  # Create the intermediate frames needed
@@ -287,7 +286,7 @@ def geometric_calibration_task_with_simple_raw_data(
287
286
  task._purge()
288
287
 
289
288
 
290
- def test_geometric_task(geometric_calibration_task_that_completes, mocker):
289
+ def test_geometric_task(geometric_calibration_task_that_completes, mocker, fake_gql_client):
291
290
  """
292
291
  Given: A set of raw solar gain images and necessary intermediate calibrations
293
292
  When: Running the geometric task
@@ -295,7 +294,7 @@ def test_geometric_task(geometric_calibration_task_that_completes, mocker):
295
294
  """
296
295
  # See the note in the fixture above: this test does NOT test for accuracy of the calibration
297
296
  mocker.patch(
298
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
297
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
299
298
  )
300
299
  task, beam_shape = geometric_calibration_task_that_completes
301
300
  task()
@@ -6,7 +6,6 @@ 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
8
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
9
- from dkist_processing_common.tests.conftest import FakeGQLClient
10
9
 
11
10
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
12
11
  from dkist_processing_cryonirsp.tasks.make_movie_frames import SPMakeCryonirspMovieFrames
@@ -95,14 +94,14 @@ def sp_movie_frames_task(tmp_path, recipe_run_id, init_cryonirsp_constants_db, r
95
94
  task._purge()
96
95
 
97
96
 
98
- def test_sp_make_movie_frames(sp_movie_frames_task, mocker):
97
+ def test_sp_make_movie_frames(sp_movie_frames_task, mocker, fake_gql_client):
99
98
  """
100
99
  Given: A SPMakeCryonirspMovieFrames task
101
100
  When: Calling the task instance
102
101
  Then: a fits file is made for each scan containing the movie frame for that scan
103
102
  """
104
103
  mocker.patch(
105
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
104
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
106
105
  )
107
106
  task, map_scans, scan_steps, array_shape, is_polarimetric = sp_movie_frames_task
108
107
  if scan_steps > 1:
@@ -11,7 +11,6 @@ from dkist_header_validator import spec122_validator
11
11
  from dkist_processing_common._util.scratch import WorkflowFileSystem
12
12
  from dkist_processing_common.codecs.fits import fits_array_encoder
13
13
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
14
- from dkist_processing_common.tests.conftest import FakeGQLClient
15
14
 
16
15
  from dkist_processing_cryonirsp.models.exposure_conditions import AllowableOpticalDensityFilterNames
17
16
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
@@ -20,8 +19,8 @@ from dkist_processing_cryonirsp.models.tags import CryonirspTag
20
19
  from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import CryonirspL0FitsAccess
21
20
  from dkist_processing_cryonirsp.tasks.sp_science import CalibrationCollection
22
21
  from dkist_processing_cryonirsp.tasks.sp_science import SPScienceCalibration
23
- from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
24
22
  from dkist_processing_cryonirsp.tests.conftest import CryonirspConstantsDb
23
+ from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
25
24
  from dkist_processing_cryonirsp.tests.conftest import generate_fits_frame
26
25
  from dkist_processing_cryonirsp.tests.header_models import CryonirspHeadersValidObserveFrames
27
26
 
@@ -67,7 +66,7 @@ def sp_science_calibration_task(
67
66
  task.scratch = WorkflowFileSystem(
68
67
  scratch_base_path=tmp_path, recipe_run_id=recipe_run_id
69
68
  )
70
- param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
69
+ param_class = cryonirsp_testing_parameters_factory(task)
71
70
  assign_input_dataset_doc_to_task(task, param_class())
72
71
  # Create fake bad pixel map
73
72
  task.write(
@@ -320,7 +319,7 @@ def calibrated_array_and_header_dicts(
320
319
  return array_dict, header_dict, array_shape
321
320
 
322
321
 
323
- def test_sp_science_calibration_task(sp_science_calibration_task, mocker):
322
+ def test_sp_science_calibration_task(sp_science_calibration_task, mocker, fake_gql_client):
324
323
  """
325
324
  Given: A SPScienceCalibration task
326
325
  When: Calling the task instance
@@ -328,7 +327,7 @@ def test_sp_science_calibration_task(sp_science_calibration_task, mocker):
328
327
  """
329
328
 
330
329
  mocker.patch(
331
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
330
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
332
331
  )
333
332
 
334
333
  # When
@@ -5,15 +5,14 @@ import pytest
5
5
  from dkist_processing_common._util.scratch import WorkflowFileSystem
6
6
  from dkist_processing_common.codecs.fits import fits_array_encoder
7
7
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
8
- from dkist_processing_common.tests.conftest import FakeGQLClient
9
8
 
10
9
  from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
11
10
  from dkist_processing_cryonirsp.models.exposure_conditions import AllowableOpticalDensityFilterNames
12
11
  from dkist_processing_cryonirsp.models.exposure_conditions import ExposureConditions
13
12
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
14
13
  from dkist_processing_cryonirsp.tasks.sp_solar_gain import SPSolarGainCalibration
15
- from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
16
14
  from dkist_processing_cryonirsp.tests.conftest import CryonirspConstantsDb
15
+ from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
17
16
  from dkist_processing_cryonirsp.tests.conftest import generate_214_l0_fits_frame
18
17
  from dkist_processing_cryonirsp.tests.header_models import CryonirspHeadersValidSPSolarGainFrames
19
18
 
@@ -51,7 +50,7 @@ def solar_gain_calibration_task_that_completes(
51
50
  task.scratch = WorkflowFileSystem(
52
51
  scratch_base_path=tmp_path, recipe_run_id=recipe_run_id
53
52
  )
54
- param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
53
+ param_class = cryonirsp_testing_parameters_factory(task)
55
54
  assign_input_dataset_doc_to_task(
56
55
  task, param_class(cryonirsp_fringe_correction_on=fringe_correction)
57
56
  )
@@ -178,14 +177,16 @@ def solar_gain_calibration_task_with_no_data(tmp_path, recipe_run_id, init_cryon
178
177
 
179
178
 
180
179
  @pytest.mark.parametrize("fringe_correction", [False, True])
181
- def test_solar_gain_task(solar_gain_calibration_task_that_completes, mocker, fringe_correction):
180
+ def test_solar_gain_task(
181
+ solar_gain_calibration_task_that_completes, mocker, fake_gql_client, fringe_correction
182
+ ):
182
183
  """
183
184
  Given: A set of raw solar gain images and necessary intermediate calibrations
184
185
  When: Running the solargain task
185
186
  Then: The task completes and the outputs are correct
186
187
  """
187
188
  mocker.patch(
188
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
189
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
189
190
  )
190
191
 
191
192
  task, true_solar_single_beam = solar_gain_calibration_task_that_completes
@@ -2,21 +2,17 @@ from datetime import datetime
2
2
 
3
3
  import numpy as np
4
4
  import pytest
5
- from astropy import units as u
6
5
  from astropy.io import fits
7
6
  from dkist_header_validator import spec122_validator
8
7
  from dkist_processing_common._util.scratch import WorkflowFileSystem
9
- from dkist_processing_common.codecs.asdf import asdf_decoder
10
8
  from dkist_processing_common.codecs.fits import fits_array_encoder
11
9
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
12
- from dkist_processing_common.tests.conftest import FakeGQLClient
10
+ from dkist_processing_common.codecs.json import json_decoder
13
11
 
14
12
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
15
- from dkist_processing_cryonirsp.tasks.sp_dispersion_axis_correction import (
16
- SPDispersionAxisCorrection,
17
- )
18
- from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
13
+ from dkist_processing_cryonirsp.tasks.sp_wavelength_calibration import SPWavelengthCalibration
19
14
  from dkist_processing_cryonirsp.tests.conftest import CryonirspConstantsDb
15
+ from dkist_processing_cryonirsp.tests.conftest import cryonirsp_testing_parameters_factory
20
16
  from dkist_processing_cryonirsp.tests.conftest import generate_fits_frame
21
17
  from dkist_processing_cryonirsp.tests.header_models import CryonirspHeadersValidSPSolarGainFrames
22
18
 
@@ -44,10 +40,10 @@ def sp_dispersion_axis_correction_task(
44
40
  GRATING_POSITION_DEG=grating_position_deg,
45
41
  GRATING_LITTROW_ANGLE_DEG=grating_littrow_angle,
46
42
  GRATING_CONSTANT=grating_constant,
47
- SOLAR_GAIN_IP_START_TIME="2021-01-01T00:00:00",
43
+ SOLAR_GAIN_START_TIME="2021-01-01T00:00:00",
48
44
  )
49
45
  init_cryonirsp_constants_db(recipe_run_id, constants_db)
50
- with SPDispersionAxisCorrection(
46
+ with SPWavelengthCalibration(
51
47
  recipe_run_id=recipe_run_id,
52
48
  workflow_name="sp_dispersion_axis_correction",
53
49
  workflow_version="VX.Y",
@@ -57,7 +53,7 @@ def sp_dispersion_axis_correction_task(
57
53
  task.scratch = WorkflowFileSystem(
58
54
  scratch_base_path=tmp_path, recipe_run_id=recipe_run_id
59
55
  )
60
- param_class = cryonirsp_testing_parameters_factory(param_path=tmp_path)
56
+ param_class = cryonirsp_testing_parameters_factory(task)
61
57
  assign_input_dataset_doc_to_task(task, param_class())
62
58
 
63
59
  # Create fake solar charcteristic spectra
@@ -99,6 +95,8 @@ def sp_dispersion_axis_correction_task(
99
95
  )
100
96
  hdul = generate_fits_frame(header_generator=header_generator, shape=array_shape)
101
97
  header = hdul[0].header
98
+ # set the slit width to a realistic Cryo value
99
+ header["CNSLITW"] = 175
102
100
  task.write(
103
101
  data=hdul,
104
102
  tags=[
@@ -115,14 +113,14 @@ def sp_dispersion_axis_correction_task(
115
113
  task._purge()
116
114
 
117
115
 
118
- def test_sp_dispersion_axis_correction(sp_dispersion_axis_correction_task, mocker):
116
+ def test_sp_dispersion_axis_correction(sp_dispersion_axis_correction_task, mocker, fake_gql_client):
119
117
  """
120
118
  Given: A SPDispersionAxisCorrection task
121
119
  When: Calling the task instance
122
120
  Then: There are the expected number of intermediate fit frames with the correct tags applied and the values have been correctly fit
123
121
  """
124
122
  mocker.patch(
125
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
123
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
126
124
  )
127
125
 
128
126
  task, original_header = sp_dispersion_axis_correction_task
@@ -131,23 +129,7 @@ def test_sp_dispersion_axis_correction(sp_dispersion_axis_correction_task, mocke
131
129
  CryonirspTag.task_spectral_fit(),
132
130
  CryonirspTag.intermediate(),
133
131
  ]
134
- fit_result = next(task.read(tags=tags, decoder=asdf_decoder))
135
- del fit_result["asdf_library"]
136
- del fit_result["history"]
137
-
138
- expected_wavelength_vector = task.compute_expected_wavelength_vector(
139
- np.random.rand(100), original_header
140
- )
141
-
142
- (
143
- telluric_atlas_wave,
144
- telluric_atlas_trans,
145
- solar_atlas_wave_air,
146
- solar_atlas_trans_flipped,
147
- ) = task.load_and_resample_fts_atlas(expected_wavelength_vector)
148
-
149
- assert len(telluric_atlas_wave) == len(telluric_atlas_trans)
150
- assert len(solar_atlas_wave_air) == len(solar_atlas_trans_flipped)
132
+ fit_result = next(task.read(tags=tags, decoder=json_decoder))
151
133
 
152
134
  # make sure that the values have changed
153
135
  assert original_header["CRVAL1"] != fit_result["CRVAL1"]
@@ -49,7 +49,7 @@ def create_trial_quality_report_task(
49
49
  )
50
50
  task.write(
51
51
  quality_data_warning_only,
52
- tags=CryonirspTag.quality_data(),
52
+ tags=[CryonirspTag.output(), CryonirspTag.quality_data()],
53
53
  encoder=quality_data_encoder,
54
54
  relative_path=f"{task.constants.dataset_id}_quality_data.json",
55
55
  )
@@ -1,4 +1,5 @@
1
1
  """Test integrity of workflows."""
2
+
2
3
  from dkist_processing_core.build_utils import validate_workflows
3
4
 
4
5
  from dkist_processing_cryonirsp import workflows
@@ -7,9 +7,8 @@ from astropy.io import fits
7
7
  from astropy.time import Time
8
8
  from dkist_fits_specifications import __version__ as spec_version
9
9
  from dkist_header_validator import spec214_validator
10
- from dkist_processing_common.codecs.asdf import asdf_encoder
11
10
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
12
- from dkist_processing_common.tests.conftest import FakeGQLClient
11
+ from dkist_processing_common.codecs.json import json_encoder
13
12
 
14
13
  from dkist_processing_cryonirsp.models.tags import CryonirspTag
15
14
  from dkist_processing_cryonirsp.tasks.write_l1 import CIWriteL1Frame
@@ -100,7 +99,7 @@ def write_l1_task(
100
99
  hdul[0].header["CNSPINMD"] = "None"
101
100
 
102
101
  if arm_id == "SP":
103
- write_dummy_sp_dispersion_intermediate(task, hdul[0].header)
102
+ write_dummy_sp_dispersion_intermediate(task)
104
103
 
105
104
  for map_scan in range(1, num_map_scans + 1):
106
105
  for scan_step in range(1, num_scan_steps + 1):
@@ -127,24 +126,24 @@ def write_l1_task(
127
126
  task._purge()
128
127
 
129
128
 
130
- def write_dummy_sp_dispersion_intermediate(task: SPWriteL1Frame, header: fits.Header) -> None:
131
- overwrite_keys = [
132
- "CRVAL1",
133
- "CDELT1",
134
- "CRVAL1A",
135
- "CDELT1A",
136
- ]
129
+ def write_dummy_sp_dispersion_intermediate(task: SPWriteL1Frame) -> None:
130
+ dummy_fit_solution = {
131
+ "CTYPE1": "AWAV-GRA",
132
+ "CUNIT1": "nm",
133
+ "CRPIX1": 5, # This needs to be 5 for `axis_flip_tests`
134
+ "CRVAL1": 9999.0,
135
+ "CDELT1": 4.56,
136
+ "PV1_0": 78.9,
137
+ "PV1_1": 51,
138
+ "PV1_2": 11121,
139
+ }
137
140
 
138
- # Guaranteed to be different than the OG header values
139
- dummy_fit_solution = {k: header[k] * (np.random.random() + 1.1) for k in overwrite_keys}
140
- dummy_fit_solution["PV1_0"] = np.random.random()
141
- dummy_fit_solution["PV1_1"] = np.random.randint(4)
142
- dummy_fit_solution["PV1_2"] = np.random.random()
141
+ dummy_fit_solution = dummy_fit_solution | {f"{k}A": v for k, v in dummy_fit_solution.items()}
143
142
 
144
143
  task.write(
145
144
  data=dummy_fit_solution,
146
145
  tags=[CryonirspTag.intermediate(), CryonirspTag.task_spectral_fit()],
147
- encoder=asdf_encoder,
146
+ encoder=json_encoder,
148
147
  )
149
148
 
150
149
 
@@ -164,14 +163,16 @@ def write_dummy_sp_dispersion_intermediate(task: SPWriteL1Frame, header: fits.He
164
163
  "arm_id",
165
164
  [pytest.param("CI", id="CI"), pytest.param("SP", id="SP")],
166
165
  )
167
- def test_write_l1_frame(write_l1_task, mocker, arm_id, num_stokes_params, num_map_scans, num_meas):
166
+ def test_write_l1_frame(
167
+ write_l1_task, mocker, fake_gql_client, arm_id, num_stokes_params, num_map_scans, num_meas
168
+ ):
168
169
  """
169
170
  :Given: a write L1 task
170
171
  :When: running the task
171
172
  :Then: the correct header keys are written
172
173
  """
173
174
  mocker.patch(
174
- "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
175
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
175
176
  )
176
177
  task, stokes_params, original_headers = write_l1_task
177
178
  task()
@@ -221,6 +222,14 @@ def test_write_l1_frame(write_l1_task, mocker, arm_id, num_stokes_params, num_ma
221
222
  axis_num += 1
222
223
  stokes_axis_tests(axis_num, header)
223
224
 
225
+ # Timing header keys
226
+ if task.constants.correct_for_polarization:
227
+ assert header["CADENCE"] == 20 * num_meas
228
+ assert header["XPOSURE"] == 30
229
+ else:
230
+ assert header["CADENCE"] == 10 * num_meas
231
+ assert header["XPOSURE"] == 15
232
+
224
233
  # Other general tests
225
234
  general_header_tests(axis_num, header, task, arm_id)
226
235
 
@@ -421,16 +430,5 @@ def general_header_tests(
421
430
  ).isot
422
431
  assert header["DATE-AVG"] == date_avg
423
432
  assert isinstance(header["HLSVERS"], str)
424
- assert header["NSPECLNS"] == 1
425
- assert header["WAVEBAND"] == "He I (1083.0 nm)"
426
- assert header["SPECLN01"] == "He I (1083.0 nm)"
427
- with pytest.raises(KeyError):
428
- header["SPECLN02"]
429
-
430
- # wavelength range tests
431
- if arm_id == "SP":
432
- assert round(header["WAVEMIN"], 2) == 1082
433
- assert round(header["WAVEMAX"], 2) == 1084
434
- if arm_id == "CI":
435
- assert header["WAVEMIN"] == 1082.5
436
- assert header["WAVEMAX"] == 1083.5
433
+ assert header["BUNIT"] == ""
434
+ assert header.comments["BUNIT"] == "Values are relative to disk center. See calibration docs."
@@ -1,2 +1,3 @@
1
1
  """Workflow package."""
2
+
2
3
  from dkist_processing_cryonirsp.config import dkist_processing_cryonirsp_configurations
@@ -1,4 +1,5 @@
1
1
  """Cryo CI raw data processing workflow."""
2
+
2
3
  from dkist_processing_common.tasks import PublishCatalogAndQualityMessages
3
4
  from dkist_processing_common.tasks import QualityL1Metrics
4
5
  from dkist_processing_common.tasks import SubmitDatasetMetadata
@@ -11,9 +12,7 @@ from dkist_processing_core import Workflow
11
12
  from dkist_processing_cryonirsp.tasks import AssembleCryonirspMovie
12
13
  from dkist_processing_cryonirsp.tasks import BadPixelMapCalibration
13
14
  from dkist_processing_cryonirsp.tasks import CIBeamBoundariesCalibration
14
- from dkist_processing_cryonirsp.tasks import (
15
- CIInstrumentPolarizationCalibration,
16
- )
15
+ from dkist_processing_cryonirsp.tasks import CIInstrumentPolarizationCalibration
17
16
  from dkist_processing_cryonirsp.tasks import CIScienceCalibration
18
17
  from dkist_processing_cryonirsp.tasks import CISolarGainCalibration
19
18
  from dkist_processing_cryonirsp.tasks import CIWriteL1Frame
@@ -66,8 +65,13 @@ l0_pipeline.add_node(
66
65
  )
67
66
 
68
67
  # Output flow
69
- l0_pipeline.add_node(task=SubmitDatasetMetadata, upstreams=[CIWriteL1Frame, CIAssembleQualityData])
70
- l0_pipeline.add_node(task=TransferL1Data, upstreams=[CIWriteL1Frame, AssembleCryonirspMovie])
68
+ l0_pipeline.add_node(
69
+ task=SubmitDatasetMetadata,
70
+ upstreams=[CIWriteL1Frame, AssembleCryonirspMovie],
71
+ )
72
+ l0_pipeline.add_node(
73
+ task=TransferL1Data, upstreams=[CIWriteL1Frame, AssembleCryonirspMovie, CIAssembleQualityData]
74
+ )
71
75
  l0_pipeline.add_node(
72
76
  task=PublishCatalogAndQualityMessages, upstreams=[SubmitDatasetMetadata, TransferL1Data]
73
77
  )
@@ -1,4 +1,5 @@
1
1
  """Cryo SP raw data processing workflow."""
2
+
2
3
  from dkist_processing_common.tasks import PublishCatalogAndQualityMessages
3
4
  from dkist_processing_common.tasks import QualityL1Metrics
4
5
  from dkist_processing_common.tasks import SubmitDatasetMetadata
@@ -18,13 +19,11 @@ from dkist_processing_cryonirsp.tasks import LinearityCorrection
18
19
  from dkist_processing_cryonirsp.tasks import MakeCryonirspMovieFrames
19
20
  from dkist_processing_cryonirsp.tasks import ParseL0CryonirspRampData
20
21
  from dkist_processing_cryonirsp.tasks import SPBeamBoundariesCalibration
21
- from dkist_processing_cryonirsp.tasks import SPDispersionAxisCorrection
22
22
  from dkist_processing_cryonirsp.tasks import SPGeometricCalibration
23
- from dkist_processing_cryonirsp.tasks import (
24
- SPInstrumentPolarizationCalibration,
25
- )
23
+ from dkist_processing_cryonirsp.tasks import SPInstrumentPolarizationCalibration
26
24
  from dkist_processing_cryonirsp.tasks import SPScienceCalibration
27
25
  from dkist_processing_cryonirsp.tasks import SPSolarGainCalibration
26
+ from dkist_processing_cryonirsp.tasks import SPWavelengthCalibration
28
27
  from dkist_processing_cryonirsp.tasks import SPWriteL1Frame
29
28
  from dkist_processing_cryonirsp.tasks.l1_output_data import SPAssembleQualityData
30
29
  from dkist_processing_cryonirsp.tasks.parse import ParseL0CryonirspSPLinearizedData
@@ -52,11 +51,11 @@ l0_pipeline.add_node(task=DarkCalibration, upstreams=SPBeamBoundariesCalibration
52
51
  l0_pipeline.add_node(task=LampGainCalibration, upstreams=DarkCalibration)
53
52
  l0_pipeline.add_node(task=SPGeometricCalibration, upstreams=LampGainCalibration)
54
53
  l0_pipeline.add_node(task=SPSolarGainCalibration, upstreams=SPGeometricCalibration)
55
- l0_pipeline.add_node(task=SPDispersionAxisCorrection, upstreams=SPSolarGainCalibration)
54
+ l0_pipeline.add_node(task=SPWavelengthCalibration, upstreams=SPSolarGainCalibration)
56
55
  l0_pipeline.add_node(task=SPInstrumentPolarizationCalibration, upstreams=SPSolarGainCalibration)
57
56
  l0_pipeline.add_node(
58
57
  task=SPScienceCalibration,
59
- upstreams=[SPInstrumentPolarizationCalibration, SPDispersionAxisCorrection],
58
+ upstreams=[SPInstrumentPolarizationCalibration, SPWavelengthCalibration],
60
59
  )
61
60
  l0_pipeline.add_node(task=SPWriteL1Frame, upstreams=SPScienceCalibration)
62
61
 
@@ -74,8 +73,13 @@ l0_pipeline.add_node(
74
73
  )
75
74
 
76
75
  # Output flow
77
- l0_pipeline.add_node(task=SubmitDatasetMetadata, upstreams=[SPWriteL1Frame, SPAssembleQualityData])
78
- l0_pipeline.add_node(task=TransferL1Data, upstreams=[SPWriteL1Frame, AssembleCryonirspMovie])
76
+ l0_pipeline.add_node(
77
+ task=SubmitDatasetMetadata,
78
+ upstreams=[SPWriteL1Frame, AssembleCryonirspMovie],
79
+ )
80
+ l0_pipeline.add_node(
81
+ task=TransferL1Data, upstreams=[SPWriteL1Frame, AssembleCryonirspMovie, SPAssembleQualityData]
82
+ )
79
83
  l0_pipeline.add_node(
80
84
  task=PublishCatalogAndQualityMessages, upstreams=[SubmitDatasetMetadata, TransferL1Data]
81
85
  )
@@ -1,4 +1,5 @@
1
1
  """Workflows for trial runs (i.e., not Production)."""
2
+
2
3
  from dkist_processing_common.tasks import CreateTrialAsdf
3
4
  from dkist_processing_common.tasks import CreateTrialDatasetInventory
4
5
  from dkist_processing_common.tasks import CreateTrialQualityReport
@@ -12,9 +13,7 @@ from dkist_processing_core import Workflow
12
13
  from dkist_processing_cryonirsp.tasks import AssembleCryonirspMovie
13
14
  from dkist_processing_cryonirsp.tasks import BadPixelMapCalibration
14
15
  from dkist_processing_cryonirsp.tasks import CIBeamBoundariesCalibration
15
- from dkist_processing_cryonirsp.tasks import (
16
- CIInstrumentPolarizationCalibration,
17
- )
16
+ from dkist_processing_cryonirsp.tasks import CIInstrumentPolarizationCalibration
18
17
  from dkist_processing_cryonirsp.tasks import CIScienceCalibration
19
18
  from dkist_processing_cryonirsp.tasks import CISolarGainCalibration
20
19
  from dkist_processing_cryonirsp.tasks import CIWriteL1Frame
@@ -26,13 +25,11 @@ from dkist_processing_cryonirsp.tasks import LinearityCorrection
26
25
  from dkist_processing_cryonirsp.tasks import MakeCryonirspMovieFrames
27
26
  from dkist_processing_cryonirsp.tasks import ParseL0CryonirspRampData
28
27
  from dkist_processing_cryonirsp.tasks import SPBeamBoundariesCalibration
29
- from dkist_processing_cryonirsp.tasks import SPDispersionAxisCorrection
30
28
  from dkist_processing_cryonirsp.tasks import SPGeometricCalibration
31
- from dkist_processing_cryonirsp.tasks import (
32
- SPInstrumentPolarizationCalibration,
33
- )
29
+ from dkist_processing_cryonirsp.tasks import SPInstrumentPolarizationCalibration
34
30
  from dkist_processing_cryonirsp.tasks import SPScienceCalibration
35
31
  from dkist_processing_cryonirsp.tasks import SPSolarGainCalibration
32
+ from dkist_processing_cryonirsp.tasks import SPWavelengthCalibration
36
33
  from dkist_processing_cryonirsp.tasks import SPWriteL1Frame
37
34
  from dkist_processing_cryonirsp.tasks.l1_output_data import CIAssembleQualityData
38
35
  from dkist_processing_cryonirsp.tasks.l1_output_data import SPAssembleQualityData
@@ -93,7 +90,9 @@ full_trial_ci_pipeline.add_node(
93
90
  )
94
91
  full_trial_ci_pipeline.add_node(task=CreateTrialAsdf, upstreams=CIWriteL1Frame, pip_extras=["asdf"])
95
92
  full_trial_ci_pipeline.add_node(
96
- task=CreateTrialQualityReport, upstreams=CIAssembleQualityData, pip_extras=["quality"]
93
+ task=CreateTrialQualityReport,
94
+ upstreams=CIAssembleQualityData,
95
+ pip_extras=["quality", "inventory"],
97
96
  )
98
97
 
99
98
  # Output flow
@@ -139,14 +138,14 @@ full_trial_sp_pipeline.add_node(task=DarkCalibration, upstreams=SPBeamBoundaries
139
138
  full_trial_sp_pipeline.add_node(task=LampGainCalibration, upstreams=DarkCalibration)
140
139
  full_trial_sp_pipeline.add_node(task=SPGeometricCalibration, upstreams=LampGainCalibration)
141
140
  full_trial_sp_pipeline.add_node(task=SPSolarGainCalibration, upstreams=SPGeometricCalibration)
142
- full_trial_sp_pipeline.add_node(task=SPDispersionAxisCorrection, upstreams=SPSolarGainCalibration)
141
+ full_trial_sp_pipeline.add_node(task=SPWavelengthCalibration, upstreams=SPSolarGainCalibration)
143
142
 
144
143
  full_trial_sp_pipeline.add_node(
145
144
  task=SPInstrumentPolarizationCalibration, upstreams=SPSolarGainCalibration
146
145
  )
147
146
  full_trial_sp_pipeline.add_node(
148
147
  task=SPScienceCalibration,
149
- upstreams=[SPInstrumentPolarizationCalibration, SPDispersionAxisCorrection],
148
+ upstreams=[SPInstrumentPolarizationCalibration, SPWavelengthCalibration],
150
149
  )
151
150
  full_trial_sp_pipeline.add_node(task=SPWriteL1Frame, upstreams=SPScienceCalibration)
152
151
 
@@ -171,7 +170,9 @@ full_trial_sp_pipeline.add_node(
171
170
  )
172
171
  full_trial_sp_pipeline.add_node(task=CreateTrialAsdf, upstreams=SPWriteL1Frame, pip_extras=["asdf"])
173
172
  full_trial_sp_pipeline.add_node(
174
- task=CreateTrialQualityReport, upstreams=SPAssembleQualityData, pip_extras=["quality"]
173
+ task=CreateTrialQualityReport,
174
+ upstreams=SPAssembleQualityData,
175
+ pip_extras=["quality", "inventory"],
175
176
  )
176
177
 
177
178
  # Output flow