dkist-processing-visp 5.6.4__tar.gz → 5.6.5__tar.gz

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 (117) hide show
  1. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/.readthedocs.yml +1 -1
  2. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/CHANGELOG.rst +16 -0
  3. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/PKG-INFO +11 -11
  4. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/conftest.py +118 -23
  5. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/header_models.py +34 -121
  6. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/local_trial_workflows/l0_polcals_as_science.py +6 -7
  7. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/local_trial_workflows/local_trial_helpers.py +18 -21
  8. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_dark.py +2 -3
  9. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_instrument_polarization.py +32 -117
  10. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_lamp.py +3 -2
  11. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_make_movie_frames.py +3 -3
  12. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_parse.py +20 -98
  13. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_polcal_as_science.py +19 -36
  14. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_science.py +10 -51
  15. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_wavelength_calibration.py +1 -0
  16. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_write_l1.py +7 -6
  17. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp.egg-info/PKG-INFO +11 -11
  18. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp.egg-info/requires.txt +10 -10
  19. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/pyproject.toml +20 -12
  20. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/.gitignore +0 -0
  21. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/.pre-commit-config.yaml +0 -0
  22. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/.snyk +0 -0
  23. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/README.rst +0 -0
  24. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/SCIENCE_CHANGELOG.rst +0 -0
  25. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/bitbucket-pipelines.yml +0 -0
  26. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/changelog/.gitempty +0 -0
  27. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/__init__.py +0 -0
  28. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/config.py +0 -0
  29. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/fonts/Lato-Regular.ttf +0 -0
  30. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/__init__.py +0 -0
  31. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/constants.py +0 -0
  32. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/dataset_extras.py +0 -0
  33. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/fits_access.py +0 -0
  34. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/metric_code.py +0 -0
  35. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/parameters.py +0 -0
  36. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/tags.py +0 -0
  37. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/models/task_name.py +0 -0
  38. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/__init__.py +0 -0
  39. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/map_repeats.py +0 -0
  40. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/modulator_states.py +0 -0
  41. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/polarimeter_mode.py +0 -0
  42. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/raster_step.py +0 -0
  43. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/spectrograph_configuration.py +0 -0
  44. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/time.py +0 -0
  45. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/visp_l0_fits_access.py +0 -0
  46. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/parsers/visp_l1_fits_access.py +0 -0
  47. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/__init__.py +0 -0
  48. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/assemble_movie.py +0 -0
  49. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/background_light.py +0 -0
  50. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/dark.py +0 -0
  51. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/geometric.py +0 -0
  52. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/instrument_polarization.py +0 -0
  53. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/l1_output_data.py +0 -0
  54. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/lamp.py +0 -0
  55. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/make_movie_frames.py +0 -0
  56. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/mixin/__init__.py +0 -0
  57. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/mixin/beam_access.py +0 -0
  58. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/mixin/corrections.py +0 -0
  59. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/mixin/downsample.py +0 -0
  60. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/parse.py +0 -0
  61. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/polcal_as_science.py +0 -0
  62. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/quality_metrics.py +0 -0
  63. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/science.py +0 -0
  64. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/solar.py +0 -0
  65. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/visp_base.py +0 -0
  66. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/wavelength_calibration.py +0 -0
  67. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/write_dataset_extras.py +0 -0
  68. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tasks/write_l1.py +0 -0
  69. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/README.rst +0 -0
  70. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/__init__.py +0 -0
  71. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/local_trial_workflows/__init__.py +0 -0
  72. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/local_trial_workflows/l0_cals_only.py +0 -0
  73. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/local_trial_workflows/l0_solar_gain_as_science.py +0 -0
  74. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/local_trial_workflows/l0_to_l1.py +0 -0
  75. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_assemble_movie.py +0 -0
  76. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_assemble_quality.py +0 -0
  77. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_background_light.py +0 -0
  78. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_downsample.py +0 -0
  79. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_fits_access.py +0 -0
  80. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_geometric.py +0 -0
  81. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_map_repeats.py +0 -0
  82. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_parameters.py +0 -0
  83. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_quality.py +0 -0
  84. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_solar.py +0 -0
  85. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_trial_create_quality_report.py +0 -0
  86. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_visp_constants.py +0 -0
  87. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_workflows.py +0 -0
  88. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/tests/test_write_dataset_extras.py +0 -0
  89. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/workflows/__init__.py +0 -0
  90. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/workflows/l0_processing.py +0 -0
  91. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/workflows/single_task_workflows.py +0 -0
  92. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp/workflows/trial_workflows.py +0 -0
  93. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp.egg-info/SOURCES.txt +0 -0
  94. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp.egg-info/dependency_links.txt +0 -0
  95. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/dkist_processing_visp.egg-info/top_level.txt +0 -0
  96. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/Makefile +0 -0
  97. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/background_light.rst +0 -0
  98. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/changelog.rst +0 -0
  99. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/conf.py +0 -0
  100. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/dataset_extras.rst +0 -0
  101. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/gain_correction.rst +0 -0
  102. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/geometric.rst +0 -0
  103. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/index.rst +0 -0
  104. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/l0_to_l1_visp.rst +0 -0
  105. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/l0_to_l1_visp_full-trial.rst +0 -0
  106. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/landing_page.rst +0 -0
  107. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/make.bat +0 -0
  108. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/polarization_calibration.rst +0 -0
  109. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/requirements.txt +0 -0
  110. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/requirements_table.rst +0 -0
  111. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/science_calibration.rst +0 -0
  112. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/scientific_changelog.rst +0 -0
  113. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/docs/wavelength_calibration.rst +0 -0
  114. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/licenses/LICENSE.rst +0 -0
  115. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/science_towncrier.sh +0 -0
  116. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/setup.cfg +0 -0
  117. {dkist_processing_visp-5.6.4 → dkist_processing_visp-5.6.5}/towncrier_science.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  version: 2
2
2
  build:
3
- os: ubuntu-20.04
3
+ os: ubuntu-24.04
4
4
  tools:
5
5
  python: "3.13"
6
6
  apt_packages:
@@ -1,3 +1,19 @@
1
+ v5.6.5 (2026-04-16)
2
+ ===================
3
+
4
+ Misc
5
+ ----
6
+
7
+ - Update test demodulation matrices to have a gradient. (`#281 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/281>`__)
8
+ - Configure pyproject.toml to turn warnings raised during testing into errors.
9
+ Ignore certain testing warnings that we know are okay. (`#281 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/281>`__)
10
+ - Remove CompImageHeader tests due to Astropy deprecation. (`#281 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/281>`__)
11
+ - Convert fits.open usage in tests to context managers. (`#281 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/281>`__)
12
+ - Replace VispHeadersInputPolcalFrame, VispHeadersInputPolcalDarkFrames, and VispHeadersInputPolcalGainFrames with VispHeadersValidPolcalFrames which makes a completely valid Calibration Sequence (i.e., with darks, clears, etc.).
13
+ Refactor test POLCAL frame generation to correctly tag with cs_step. (`#281 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/281>`__)
14
+ - Upgrade Read the Docs LTS build image to Ubuntu 24.04. (`#300 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/300>`__)
15
+
16
+
1
17
  v5.6.4 (2026-04-14)
2
18
  ===================
3
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-processing-visp
3
- Version: 5.6.4
3
+ Version: 5.6.5
4
4
  Summary: Science processing code for the ViSP instrument on DKIST
5
5
  Author-email: NSO / AURA <dkistdc@nso.edu>
6
6
  License: BSD-3-Clause
@@ -13,12 +13,12 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/x-rst
16
- Requires-Dist: dkist-processing-common==13.0.3
16
+ Requires-Dist: dkist-processing-common==13.0.4
17
17
  Requires-Dist: dkist-processing-math==2.2.1
18
18
  Requires-Dist: dkist-processing-pac==3.1.1
19
19
  Requires-Dist: dkist-header-validator==5.3.0
20
20
  Requires-Dist: dkist-fits-specifications==4.24.0
21
- Requires-Dist: solar-wavelength-calibration==2.0.1
21
+ Requires-Dist: solar-wavelength-calibration==2.0.3
22
22
  Requires-Dist: dkist-service-configuration==4.3.0
23
23
  Requires-Dist: dkist-spectral-lines==3.0.0
24
24
  Requires-Dist: astropy==7.0.2
@@ -111,8 +111,8 @@ Requires-Dist: asyncpg==0.31.0; extra == "frozen"
111
111
  Requires-Dist: attrs==26.1.0; extra == "frozen"
112
112
  Requires-Dist: babel==2.18.0; extra == "frozen"
113
113
  Requires-Dist: billiard==4.2.4; extra == "frozen"
114
- Requires-Dist: boto3==1.42.89; extra == "frozen"
115
- Requires-Dist: botocore==1.42.89; extra == "frozen"
114
+ Requires-Dist: boto3==1.42.90; extra == "frozen"
115
+ Requires-Dist: botocore==1.42.90; extra == "frozen"
116
116
  Requires-Dist: cadwyn==5.4.6; extra == "frozen"
117
117
  Requires-Dist: celery==5.6.3; extra == "frozen"
118
118
  Requires-Dist: certifi==2026.2.25; extra == "frozen"
@@ -132,11 +132,11 @@ Requires-Dist: dacite==1.9.2; extra == "frozen"
132
132
  Requires-Dist: decorator==5.2.1; extra == "frozen"
133
133
  Requires-Dist: dill==0.4.1; extra == "frozen"
134
134
  Requires-Dist: dkist-header-validator==5.3.0; extra == "frozen"
135
- Requires-Dist: dkist-processing-common==13.0.3; extra == "frozen"
136
- Requires-Dist: dkist-processing-core==7.1.0; extra == "frozen"
135
+ Requires-Dist: dkist-processing-common==13.0.4; extra == "frozen"
136
+ Requires-Dist: dkist-processing-core==7.2.1; extra == "frozen"
137
137
  Requires-Dist: dkist-processing-math==2.2.1; extra == "frozen"
138
138
  Requires-Dist: dkist-processing-pac==3.1.1; extra == "frozen"
139
- Requires-Dist: dkist-processing-visp==5.6.4; extra == "frozen"
139
+ Requires-Dist: dkist-processing-visp==5.6.5; extra == "frozen"
140
140
  Requires-Dist: dkist-service-configuration==4.3.0; extra == "frozen"
141
141
  Requires-Dist: dkist-spectral-lines==3.0.0; extra == "frozen"
142
142
  Requires-Dist: dkist_fits_specifications==4.24.0; extra == "frozen"
@@ -235,9 +235,9 @@ Requires-Dist: protobuf==6.33.6; extra == "frozen"
235
235
  Requires-Dist: psutil==7.2.2; extra == "frozen"
236
236
  Requires-Dist: psycopg2-binary==2.9.11; extra == "frozen"
237
237
  Requires-Dist: pycparser==3.0; extra == "frozen"
238
- Requires-Dist: pydantic==2.13.0; extra == "frozen"
238
+ Requires-Dist: pydantic==2.13.1; extra == "frozen"
239
239
  Requires-Dist: pydantic-settings==2.13.1; extra == "frozen"
240
- Requires-Dist: pydantic_core==2.46.0; extra == "frozen"
240
+ Requires-Dist: pydantic_core==2.46.1; extra == "frozen"
241
241
  Requires-Dist: pyerfa==2.0.1.5; extra == "frozen"
242
242
  Requires-Dist: pygtrie==2.5.0; extra == "frozen"
243
243
  Requires-Dist: pyparsing==3.3.2; extra == "frozen"
@@ -263,7 +263,7 @@ Requires-Dist: setproctitle==1.3.7; extra == "frozen"
263
263
  Requires-Dist: shellingham==1.5.4; extra == "frozen"
264
264
  Requires-Dist: six==1.17.0; extra == "frozen"
265
265
  Requires-Dist: sniffio==1.3.1; extra == "frozen"
266
- Requires-Dist: solar-wavelength-calibration==2.0.1; extra == "frozen"
266
+ Requires-Dist: solar-wavelength-calibration==2.0.3; extra == "frozen"
267
267
  Requires-Dist: sqids==0.5.1; extra == "frozen"
268
268
  Requires-Dist: sqlparse==0.5.5; extra == "frozen"
269
269
  Requires-Dist: starlette==0.48.0; extra == "frozen"
@@ -3,14 +3,17 @@ from dataclasses import asdict
3
3
  from dataclasses import dataclass
4
4
  from dataclasses import field
5
5
  from dataclasses import is_dataclass
6
+ from functools import partial
6
7
  from random import randint
7
8
  from typing import Any
8
9
  from typing import Callable
9
10
  from typing import Type
10
11
 
12
+ import astropy.units as u
11
13
  import numpy as np
12
14
  import pytest
13
15
  from astropy.io import fits
16
+ from astropy.time import Time
14
17
  from dkist_data_simulator.spec122 import Spec122Dataset
15
18
  from dkist_header_validator.translator import sanitize_to_spec214_level1
16
19
  from dkist_header_validator.translator import translate_spec122_to_spec214_l0
@@ -28,6 +31,7 @@ from solar_wavelength_calibration import DownloadConfig
28
31
  from dkist_processing_visp.models.constants import VispConstants
29
32
  from dkist_processing_visp.models.parameters import VispParameters
30
33
  from dkist_processing_visp.models.tags import VispTag
34
+ from dkist_processing_visp.tests.header_models import VispCSStepPolcalFrames
31
35
  from dkist_processing_visp.tests.header_models import VispHeaders
32
36
  from dkist_processing_visp.tests.header_models import VispHeadersValidCalibratedFrames
33
37
 
@@ -375,6 +379,31 @@ def make_random_data(frame: Spec122Dataset) -> np.ndarray:
375
379
  return data
376
380
 
377
381
 
382
+ @dataclass
383
+ class CalibrationSequence:
384
+ pol_status: tuple = (
385
+ "clear",
386
+ "clear",
387
+ "Sapphire Polarizer",
388
+ "Sapphire Polarizer",
389
+ "Sapphire Polarizer",
390
+ "clear",
391
+ "clear",
392
+ )
393
+ pol_theta: tuple = (0.0, 0.0, 60.0, 0.0, 120.0, 0.0, 0.0)
394
+ ret_status: tuple = ("clear", "clear", "clear", "SiO2 OC", "clear", "clear", "clear")
395
+ ret_theta: tuple = (0.0, 0.0, 0.0, 45.0, 0.0, 0.0, 0.0)
396
+ dark_status: tuple = (
397
+ "DarkShutter",
398
+ "FieldStop (5arcmin)",
399
+ "FieldStop (5arcmin)",
400
+ "FieldStop (5arcmin)",
401
+ "FieldStop (5arcmin)",
402
+ "FieldStop (5arcmin)",
403
+ "DarkShutter",
404
+ )
405
+
406
+
378
407
  def tag_on_modstate(frame: VispHeaders) -> list[str]:
379
408
  """Tage a given frame based on its current modstate value."""
380
409
  modstate = frame.current_modstate(
@@ -571,33 +600,99 @@ def write_intermediate_solar_cals_to_task(
571
600
  )
572
601
 
573
602
 
574
- def write_intermediate_polcal_darks_to_task(
575
- task, *, dark_signal: float, readout_exp_time: float, data_shape: tuple[int, int]
603
+ def make_cs_data(
604
+ frame: VispCSStepPolcalFrames, dark_signal: float, clear_signal: float
605
+ ) -> np.ndarray:
606
+ shape = frame.array_shape[1:]
607
+ ny, nx = shape
608
+
609
+ y = np.linspace(0.0, 1.0, ny)[:, None]
610
+ x = np.linspace(0.0, 1.0, nx)[None, :]
611
+
612
+ modstate = frame.current_modstate("dummy_arg")
613
+ cs_step = frame.current_cs_step
614
+
615
+ gradient = 1.0 + 0.03 * x + 0.02 * y
616
+
617
+ if frame.pol_status == "clear" and frame.ret_status == "clear":
618
+ if frame.dark_status == "DarkShutter":
619
+ data = np.random.random(shape) + dark_signal
620
+ else:
621
+ data = clear_signal * gradient + dark_signal
622
+ else:
623
+ data = clear_signal * (1.0 + 0.2 * cs_step + 0.1 * modstate) * gradient + dark_signal
624
+ return data
625
+
626
+
627
+ def write_calibration_sequence_frames_to_task(
628
+ task,
629
+ num_modstates: int,
630
+ pol_status: tuple[str, ...],
631
+ pol_theta: tuple[float, ...],
632
+ ret_status: tuple[str, ...],
633
+ ret_theta: tuple[float, ...],
634
+ dark_status: tuple[str, ...],
635
+ exp_time: float = 7.0,
636
+ dark_signal: float = 5.0,
637
+ clear_signal: float = 10.0,
638
+ data_shape: tuple[int, ...] = (10, 10),
639
+ num_frames_per_cs_step: int = 1,
640
+ tags: list[str] | None = None,
641
+ tag_func: Callable = tag_on_modstate,
642
+ no_additional_tags: bool = False,
643
+ **kwargs,
576
644
  ):
577
- dark_cal = np.ones(data_shape) * dark_signal
578
- # Need a dark for each beam
579
- for beam in [1, 2]:
580
- task.write(
581
- data=dark_cal,
582
- tags=VispTag.intermediate_frame_polcal_dark(
583
- beam=beam, readout_exp_time=readout_exp_time
584
- ),
585
- encoder=fits_array_encoder,
645
+ array_shape = (1, *data_shape)
646
+ data_func = partial(make_cs_data, dark_signal=dark_signal, clear_signal=clear_signal)
647
+
648
+ base_time = Time("2023-01-01T01:23:45")
649
+
650
+ for step, (pol_s, pol_t, ret_s, ret_t, dark_s) in enumerate(
651
+ zip(pol_status, pol_theta, ret_status, ret_theta, dark_status)
652
+ ):
653
+
654
+ step_start = (base_time + (step * 60) * u.s).fits
655
+
656
+ dataset = VispCSStepPolcalFrames(
657
+ num_modstates=num_modstates,
658
+ pol_status=pol_s,
659
+ pol_theta=pol_t,
660
+ ret_status=ret_s,
661
+ dark_status=dark_s,
662
+ cs_step_num=step,
663
+ ret_theta=ret_t,
664
+ array_shape=array_shape,
665
+ exp_time=exp_time,
666
+ ip_start_time=step_start,
667
+ num_frames_per_cs_step=num_frames_per_cs_step,
668
+ **kwargs,
586
669
  )
587
670
 
671
+ if no_additional_tags:
672
+ step_tags = tags
673
+ else:
674
+ step_tags = list(
675
+ set(
676
+ tags
677
+ + [
678
+ VispTag.cs_step(step),
679
+ VispTag.task_polcal(),
680
+ ]
681
+ )
682
+ )
588
683
 
589
- def write_intermediate_polcal_gains_to_task(
590
- task, *, gain_signal: float, readout_exp_time: float, data_shape: tuple[int, int]
591
- ):
592
- gain_cal = np.ones(data_shape) * gain_signal
593
- # Need a dark for each beam
594
- for beam in [1, 2]:
595
- task.write(
596
- data=gain_cal,
597
- tags=VispTag.intermediate_frame_polcal_gain(
598
- beam=beam, readout_exp_time=readout_exp_time
599
- ),
600
- encoder=fits_array_encoder,
684
+ if pol_s == "clear" and ret_s == "clear":
685
+ if dark_s == "DarkShutter":
686
+ step_tags += [VispTag.task_polcal_dark()]
687
+ else:
688
+ step_tags += [VispTag.task_polcal_gain()]
689
+
690
+ write_frames_to_task(
691
+ task=task,
692
+ frame_generator=dataset,
693
+ data_func=data_func,
694
+ extra_tags=step_tags,
695
+ tag_func=tag_func,
601
696
  )
602
697
 
603
698
 
@@ -11,8 +11,6 @@ actually control the output of the generators themselves.
11
11
 
12
12
  import uuid
13
13
  from itertools import product
14
- from random import choice
15
- from random import random
16
14
  from random import randrange
17
15
  from typing import Literal
18
16
 
@@ -246,48 +244,53 @@ class VispHeadersInputSolarGainFrames(VispHeaders):
246
244
  return self.index + 1
247
245
 
248
246
 
249
- class VispHeadersInputPolcalFrames(VispHeaders):
247
+ class VispCSStepPolcalFrames(VispHeaders):
250
248
  def __init__(
251
249
  self,
252
- array_shape: tuple[int, ...],
253
- time_delta: float,
254
250
  num_modstates: int,
255
- num_cs_steps: int = 1,
256
- num_frames_per_cs_step: int = 1,
251
+ pol_status: str,
252
+ pol_theta: float,
253
+ ret_status: str,
254
+ ret_theta: float,
255
+ dark_status: str,
256
+ cs_step_num: int,
257
+ array_shape: tuple[int, ...],
257
258
  exp_time: float = 0.01,
259
+ num_cs_steps: int = 1,
258
260
  readout_exp_time: float = 0.02,
259
261
  ip_start_time="2022-11-28T13:50:00",
260
262
  ip_end_time="2022-11-28T13:51:00",
263
+ num_frames_per_cs_step: int = 1,
261
264
  **kwargs,
262
265
  ):
263
266
  ################################################
264
267
  # See module docstring and README for usage info
265
268
  ################################################
269
+
266
270
  num_frames = num_modstates * num_cs_steps * num_frames_per_cs_step
267
271
  dataset_shape = (num_frames, *array_shape[-2:])
272
+ indices = list(product(range(1, num_modstates + 1), range(num_frames_per_cs_step)))
273
+
268
274
  super().__init__(
269
275
  dataset_shape,
270
276
  array_shape,
271
- time_delta,
272
277
  num_modstates_header_value=num_modstates,
273
278
  ip_start_time=ip_start_time,
274
279
  ip_end_time=ip_end_time,
275
280
  **kwargs,
276
281
  )
277
- indices = list(
278
- product(
279
- range(num_cs_steps),
280
- range(1, num_modstates + 1),
281
- range(num_frames_per_cs_step),
282
- )
283
- )
284
282
 
285
- self.index_to_cs_step = [cs for (cs, _, _) in indices]
286
- self.index_to_modstate = [ms for (_, ms, _) in indices]
287
- self.index_to_cs_step_frame = [csf for (_, _, csf) in indices]
283
+ self.index_to_modstate = [ms for (ms, _) in indices]
284
+ self.index_to_cs_step_frame = [csf for (_, csf) in indices]
288
285
 
289
- self.polarizer_choices = ["Sapphire Polarizer", "clear"]
290
- self.retarder_choices = ["SiO2 OC", "clear"]
286
+ self.cs_step_num = (
287
+ cs_step_num # This doesn't become a header key, but helps with making fake data
288
+ )
289
+ self.pol_status = pol_status
290
+ self.pol_theta = pol_theta
291
+ self.ret_status = ret_status
292
+ self.ret_theta = ret_theta
293
+ self.dark_status = dark_status
291
294
 
292
295
  self.add_constant_key("DKIST004", TaskName.polcal.value.lower())
293
296
  self.add_constant_key("DKIST008", 1)
@@ -296,24 +299,24 @@ class VispHeadersInputPolcalFrames(VispHeaders):
296
299
  self.add_constant_key("VISP_020", 1)
297
300
  self.add_constant_key("TELSCAN", "Raster")
298
301
  self.add_constant_key("ID___004")
299
- self.add_constant_key("PAC__004", "Sapphire Polarizer")
300
- self.add_constant_key("PAC__005", "60.")
301
- self.add_constant_key("PAC__007", "0.0")
302
- self.add_constant_key("PAC__008", "FieldStop (5arcmin)")
302
+ self.add_constant_key("PAC__004", pol_status)
303
+ self.add_constant_key("PAC__006", ret_status)
304
+ self.add_constant_key("PAC__008", dark_status)
303
305
  self.add_constant_key("CAM__004", exp_time)
304
306
  self.add_constant_key("CAM__005", readout_exp_time)
305
307
  self.add_constant_key("CAM__014", 10)
306
308
 
307
- @key_function("PAC__006")
308
- def retarder_name(self, key: str) -> str:
309
- if self.index % 2:
310
- return self.retarder_choices[1]
311
- return self.retarder_choices[0]
309
+ @key_function("PAC__005")
310
+ def polarizer_angle(self, key: str) -> float | str:
311
+ return "none" if self.pol_status == "clear" else self.pol_theta
312
+
313
+ @key_function("PAC__007")
314
+ def retarder_angle(self, key: str) -> float | str:
315
+ return "none" if self.ret_status == "clear" else self.ret_theta
312
316
 
313
317
  @property
314
318
  def current_cs_step(self) -> int:
315
- # There is no header value for CS step; this property is used to help data generator fixtures with tagging
316
- return self.index_to_cs_step[self.index]
319
+ return self.cs_step_num
317
320
 
318
321
  @property
319
322
  def current_cs_step_frame(self) -> int:
@@ -324,96 +327,6 @@ class VispHeadersInputPolcalFrames(VispHeaders):
324
327
  def current_modstate(self, key: str) -> int:
325
328
  return self.index_to_modstate[self.index]
326
329
 
327
- @key_function("PAC__004")
328
- def polarizer(self, key: str) -> str:
329
- return choice(self.polarizer_choices)
330
-
331
- @key_function("PAC__005")
332
- def pol_angle(self, key: str) -> float:
333
- return random() * 120.0
334
-
335
- @key_function("PAC__007")
336
- def ret_angle(self, key: str) -> float:
337
- return random() * 120.0
338
-
339
-
340
- class VispHeadersInputPolcalDarkFrames(VispHeaders):
341
- def __init__(
342
- self,
343
- array_shape: tuple[int, ...],
344
- time_delta: float,
345
- num_modstates: int,
346
- exp_time: float = 0.01,
347
- readout_exp_time: float = 0.02,
348
- ip_start_time="2022-11-28T13:50:00",
349
- ip_end_time="2022-11-28T13:51:00",
350
- **kwargs,
351
- ):
352
- num_frames = num_modstates
353
- dataset_shape = (num_frames, *array_shape[-2:])
354
- super().__init__(
355
- dataset_shape,
356
- array_shape,
357
- time_delta,
358
- ip_start_time=ip_start_time,
359
- ip_end_time=ip_end_time,
360
- **kwargs,
361
- )
362
- self.add_constant_key("DKIST004", TaskName.polcal.value.lower())
363
- self.add_constant_key("DKIST008", 1)
364
- self.add_constant_key("DKIST009", 1)
365
- self.add_constant_key("VISP_019", 1)
366
- self.add_constant_key("VISP_020", 1)
367
- self.add_constant_key("TELSCAN", "Raster")
368
- self.add_constant_key("ID___004")
369
- self.add_constant_key("PAC__004", "clear")
370
- self.add_constant_key("PAC__005", "60.")
371
- self.add_constant_key("PAC__006", "clear")
372
- self.add_constant_key("PAC__007", "0.0")
373
- self.add_constant_key("PAC__008", "DarkShutter")
374
- self.add_constant_key("CAM__004", exp_time)
375
- self.add_constant_key("CAM__005", readout_exp_time)
376
- self.add_constant_key("CAM__014", 10)
377
-
378
-
379
- class VispHeadersInputPolcalGainFrames(VispHeaders):
380
- def __init__(
381
- self,
382
- array_shape: tuple[int, ...],
383
- time_delta: float,
384
- num_modstates: int,
385
- exp_time: float = 0.01,
386
- readout_exp_time: float = 0.02,
387
- ip_start_time="2022-11-28T13:50:00",
388
- ip_end_time="2022-11-28T13:51:00",
389
- **kwargs,
390
- ):
391
- num_frames = num_modstates
392
- dataset_shape = (num_frames, *array_shape[-2:])
393
- super().__init__(
394
- dataset_shape,
395
- array_shape,
396
- time_delta,
397
- ip_start_time=ip_start_time,
398
- ip_end_time=ip_end_time,
399
- **kwargs,
400
- )
401
- self.add_constant_key("DKIST004", TaskName.polcal.value.lower())
402
- self.add_constant_key("DKIST008", 1)
403
- self.add_constant_key("DKIST009", 1)
404
- self.add_constant_key("VISP_019", 1)
405
- self.add_constant_key("VISP_020", 1)
406
- self.add_constant_key("TELSCAN", "Raster")
407
- self.add_constant_key("ID___004")
408
- self.add_constant_key("PAC__004", "clear")
409
- self.add_constant_key("PAC__005", "60.")
410
- self.add_constant_key("PAC__006", "clear")
411
- self.add_constant_key("PAC__007", "0.0")
412
- self.add_constant_key("PAC__008", "FieldStop (5arcmin)")
413
- self.add_constant_key("CAM__004", exp_time)
414
- self.add_constant_key("CAM__005", readout_exp_time)
415
- self.add_constant_key("CAM__014", 10)
416
-
417
330
 
418
331
  class VispHeadersValidObserveFrames(VispHeaders):
419
332
  def __init__(
@@ -161,13 +161,12 @@ class TagPolcalAsScience(VispTaskBase):
161
161
  self.scratch._tag_db.clear_value(file_name)
162
162
  logging.info(f"\tafter removing, the tags are {self.tags(file_name)}")
163
163
 
164
- hdul = fits.open(file_name, mode="update")
165
- idx = 0
166
- if hdul[idx].data is None:
167
- idx = 1
168
- hdul[idx].header[VispMetadataKey.raster_scan_step] = raster_step
169
- hdul.flush()
170
- del hdul
164
+ with fits.open(file_name, mode="update") as hdul:
165
+ idx = 0
166
+ if hdul[idx].data is None:
167
+ idx = 1
168
+ hdul[idx].header[VispMetadataKey.raster_scan_step] = raster_step
169
+ hdul.flush()
171
170
 
172
171
  new_tags = [
173
172
  VispTag.task_observe(),
@@ -600,21 +600,18 @@ def translate_122_to_214l0_task(suffix: str):
600
600
  file
601
601
  )
602
602
  logger.info(f"Translating {file} -> {translated_file_name}")
603
- hdl = fits.open(file)
604
- i = 0
605
- if hdl[i].data is None:
606
- i = 1
607
-
608
- header = spec122_validator.validate_and_translate_to_214_l0(
609
- hdl[i].header, return_type=fits.HDUList
610
- )[0].header
611
-
612
- comp_hdu = fits.CompImageHDU(header=header, data=hdl[i].data)
613
- comp_hdl = fits.HDUList([fits.PrimaryHDU(), comp_hdu])
614
- comp_hdl.writeto(translated_file_name, overwrite=True)
615
-
616
- hdl.close()
617
- del hdl
603
+ with fits.open(file, memmap=False) as hdl:
604
+ i = 0
605
+ if hdl[i].data is None:
606
+ i = 1
607
+
608
+ header = spec122_validator.validate_and_translate_to_214_l0(
609
+ hdl[i].header, return_type=fits.HDUList
610
+ )[0].header
611
+
612
+ comp_hdu = fits.CompImageHDU(header=header, data=hdl[i].data)
613
+ comp_hdl = fits.HDUList([fits.PrimaryHDU(), comp_hdu])
614
+ comp_hdl.writeto(translated_file_name, overwrite=True)
618
615
  comp_hdl.close()
619
616
  del comp_hdl
620
617
 
@@ -648,9 +645,9 @@ class TagSingleSolarGainAsScience(VispTaskBase):
648
645
  VispTag.task_solar_gain(),
649
646
  ]
650
647
  file_list = list(self.read(tags=tags))
651
- first_hdul = fits.open(file_list[0])
652
- idx = 1 if first_hdul[0].data is None else 0
653
- first_header = first_hdul[idx].header
648
+ with fits.open(file_list[0]) as first_hdul:
649
+ idx = 1 if first_hdul[0].data is None else 0
650
+ first_header = first_hdul[idx].header
654
651
  logger.info(f"Averaging {len(file_list)} files")
655
652
  arrays = self.read(tags=tags, decoder=fits_array_decoder)
656
653
  avg_array = average_numpy_arrays(arrays=arrays)
@@ -699,9 +696,9 @@ class TagModulatedSolarGainsAsScience(VispTaskBase):
699
696
  VispTag.modstate(modstate),
700
697
  ]
701
698
  file_list = list(self.read(tags=tags))
702
- first_hdul = fits.open(file_list[0])
703
- idx = 1 if first_hdul[0].data is None else 0
704
- first_header = first_hdul[idx].header
699
+ with fits.open(file_list[0]) as first_hdul:
700
+ idx = 1 if first_hdul[0].data is None else 0
701
+ first_header = first_hdul[idx].header
705
702
  logger.info(f"Averaging {len(file_list)} files")
706
703
  arrays = self.read(tags=tags, decoder=fits_array_decoder)
707
704
  avg_array = average_numpy_arrays(arrays=arrays)
@@ -143,9 +143,8 @@ def test_dark_calibration_task(
143
143
  )
144
144
  assert len(files) == 1
145
145
  expected = np.ones((data_shape[0] // 2, data_shape[1])) * (b + 1) * e / n
146
- hdul = fits.open(files[0])
147
- np.testing.assert_allclose(expected, hdul[0].data, rtol=1e-15)
148
- hdul.close()
146
+ with fits.open(files[0], memmap=False) as hdul:
147
+ np.testing.assert_allclose(expected, hdul[0].data, rtol=1e-15)
149
148
 
150
149
  unused_time_read = task.read(
151
150
  tags=[