dkist-processing-visp 5.1.2rc2__tar.gz → 5.2.0rc1__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.1.2rc2 → dkist_processing_visp-5.2.0rc1}/CHANGELOG.rst +9 -0
  2. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/PKG-INFO +33 -33
  3. dkist_processing_visp-5.2.0rc1/changelog/234.bugfix.rst +2 -0
  4. dkist_processing_visp-5.2.0rc1/changelog/234.doc.rst +1 -0
  5. dkist_processing_visp-5.2.0rc1/changelog/234.feature.rst +1 -0
  6. dkist_processing_visp-5.2.0rc1/changelog/234.science.rst +2 -0
  7. dkist_processing_visp-5.2.0rc1/changelog/253.misc.rst +1 -0
  8. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/parameters.py +43 -1
  9. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/tags.py +11 -0
  10. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/task_name.py +2 -0
  11. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/geometric.py +1 -1
  12. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/science.py +88 -11
  13. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/solar.py +12 -205
  14. dkist_processing_visp-5.2.0rc1/dkist_processing_visp/tasks/wavelength_calibration.py +430 -0
  15. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/write_l1.py +2 -0
  16. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/conftest.py +11 -0
  17. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/header_models.py +22 -6
  18. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_cals_only.py +21 -0
  19. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_polcals_as_science.py +21 -0
  20. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_solar_gain_as_science.py +20 -0
  21. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_to_l1.py +21 -0
  22. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/local_trial_workflows/local_trial_helpers.py +27 -0
  23. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_parameters.py +11 -5
  24. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_science.py +60 -5
  25. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_solar.py +0 -1
  26. dkist_processing_visp-5.2.0rc1/dkist_processing_visp/tests/test_wavelength_calibration.py +297 -0
  27. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_write_l1.py +0 -2
  28. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/workflows/l0_processing.py +4 -1
  29. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/workflows/trial_workflows.py +4 -1
  30. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp.egg-info/PKG-INFO +33 -33
  31. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp.egg-info/SOURCES.txt +8 -1
  32. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp.egg-info/requires.txt +32 -32
  33. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/gain_correction.rst +3 -0
  34. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/index.rst +1 -0
  35. dkist_processing_visp-5.2.0rc1/docs/wavelength_calibration.rst +64 -0
  36. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/pyproject.toml +34 -34
  37. dkist_processing_visp-5.1.2rc2/changelog/251.feature.rst +0 -1
  38. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/.gitignore +0 -0
  39. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/.pre-commit-config.yaml +0 -0
  40. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/.readthedocs.yml +0 -0
  41. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/.snyk +0 -0
  42. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/README.rst +0 -0
  43. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/SCIENCE_CHANGELOG.rst +0 -0
  44. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/bitbucket-pipelines.yml +0 -0
  45. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/changelog/.gitempty +0 -0
  46. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/__init__.py +0 -0
  47. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/config.py +0 -0
  48. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/fonts/Lato-Regular.ttf +0 -0
  49. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/__init__.py +0 -0
  50. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/constants.py +0 -0
  51. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/fits_access.py +0 -0
  52. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/models/metric_code.py +0 -0
  53. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/__init__.py +0 -0
  54. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/map_repeats.py +0 -0
  55. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/modulator_states.py +0 -0
  56. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/polarimeter_mode.py +0 -0
  57. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/raster_step.py +0 -0
  58. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/spectrograph_configuration.py +0 -0
  59. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/time.py +0 -0
  60. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/visp_l0_fits_access.py +0 -0
  61. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/parsers/visp_l1_fits_access.py +0 -0
  62. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/__init__.py +0 -0
  63. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/assemble_movie.py +0 -0
  64. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/background_light.py +0 -0
  65. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/dark.py +0 -0
  66. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/instrument_polarization.py +0 -0
  67. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/l1_output_data.py +0 -0
  68. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/lamp.py +0 -0
  69. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/make_movie_frames.py +0 -0
  70. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/mixin/__init__.py +0 -0
  71. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/mixin/beam_access.py +0 -0
  72. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/mixin/corrections.py +0 -0
  73. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/mixin/downsample.py +0 -0
  74. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/parse.py +0 -0
  75. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/quality_metrics.py +0 -0
  76. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tasks/visp_base.py +0 -0
  77. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/README.rst +0 -0
  78. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/__init__.py +0 -0
  79. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/local_trial_workflows/__init__.py +0 -0
  80. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_assemble_movie.py +0 -0
  81. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_assemble_quality.py +0 -0
  82. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_background_light.py +0 -0
  83. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_dark.py +0 -0
  84. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_downsample.py +0 -0
  85. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_fits_access.py +0 -0
  86. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_geometric.py +0 -0
  87. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_instrument_polarization.py +0 -0
  88. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_lamp.py +0 -0
  89. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_make_movie_frames.py +0 -0
  90. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_map_repeats.py +0 -0
  91. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_parse.py +0 -0
  92. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_quality.py +0 -0
  93. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_trial_create_quality_report.py +0 -0
  94. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_visp_constants.py +0 -0
  95. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/tests/test_workflows.py +0 -0
  96. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/workflows/__init__.py +0 -0
  97. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp/workflows/single_task_workflows.py +0 -0
  98. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp.egg-info/dependency_links.txt +0 -0
  99. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/dkist_processing_visp.egg-info/top_level.txt +0 -0
  100. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/Makefile +0 -0
  101. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/background_light.rst +0 -0
  102. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/changelog.rst +0 -0
  103. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/conf.py +0 -0
  104. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/geometric.rst +0 -0
  105. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/l0_to_l1_visp.rst +0 -0
  106. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/l0_to_l1_visp_full-trial.rst +0 -0
  107. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/landing_page.rst +0 -0
  108. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/make.bat +0 -0
  109. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/polarization_calibration.rst +0 -0
  110. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/requirements.txt +0 -0
  111. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/requirements_table.rst +0 -0
  112. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/science_calibration.rst +0 -0
  113. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/docs/scientific_changelog.rst +0 -0
  114. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/licenses/LICENSE.rst +0 -0
  115. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/science_towncrier.sh +0 -0
  116. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/setup.cfg +0 -0
  117. {dkist_processing_visp-5.1.2rc2 → dkist_processing_visp-5.2.0rc1}/towncrier_science.toml +0 -0
@@ -1,3 +1,12 @@
1
+ v5.1.2 (2025-12-08)
2
+ ===================
3
+
4
+ Features
5
+ --------
6
+
7
+ - Store quality data in object store and revise the workflow so that VispAssembleQualityData precedes the TransferL1Data task. (`#251 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/251>`__)
8
+
9
+
1
10
  v5.1.1 (2025-12-05)
2
11
  ===================
3
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-processing-visp
3
- Version: 5.1.2rc2
3
+ Version: 5.2.0rc1
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,7 +13,7 @@ Classifier: Programming Language :: Python :: 3
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Requires-Python: >=3.12
15
15
  Description-Content-Type: text/x-rst
16
- Requires-Dist: dkist-processing-common==11.9.1rc2
16
+ Requires-Dist: dkist-processing-common==11.9.1
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.2.1
@@ -30,6 +30,7 @@ Requires-Dist: scikit-learn==1.6.1
30
30
  Requires-Dist: peakutils==1.3.5
31
31
  Requires-Dist: Pillow==10.4.0
32
32
  Requires-Dist: moviepy==2.1.2
33
+ Requires-Dist: solar-wavelength-calibration==2.0.0
33
34
  Provides-Extra: test
34
35
  Requires-Dist: pytest; extra == "test"
35
36
  Requires-Dist: pytest-cov; extra == "test"
@@ -125,8 +126,8 @@ Requires-Dist: attrs==25.4.0; extra == "frozen"
125
126
  Requires-Dist: babel==2.17.0; extra == "frozen"
126
127
  Requires-Dist: billiard==4.2.4; extra == "frozen"
127
128
  Requires-Dist: blinker==1.9.0; extra == "frozen"
128
- Requires-Dist: boto3==1.42.5; extra == "frozen"
129
- Requires-Dist: botocore==1.42.5; extra == "frozen"
129
+ Requires-Dist: boto3==1.42.8; extra == "frozen"
130
+ Requires-Dist: botocore==1.42.8; extra == "frozen"
130
131
  Requires-Dist: cachelib==0.13.0; extra == "frozen"
131
132
  Requires-Dist: celery==5.6.0; extra == "frozen"
132
133
  Requires-Dist: certifi==2025.11.12; extra == "frozen"
@@ -149,11 +150,11 @@ Requires-Dist: dacite==1.9.2; extra == "frozen"
149
150
  Requires-Dist: decorator==5.2.1; extra == "frozen"
150
151
  Requires-Dist: dill==0.4.0; extra == "frozen"
151
152
  Requires-Dist: dkist-header-validator==5.2.1; extra == "frozen"
152
- Requires-Dist: dkist-processing-common==11.9.1rc2; extra == "frozen"
153
+ Requires-Dist: dkist-processing-common==11.9.1; extra == "frozen"
153
154
  Requires-Dist: dkist-processing-core==6.0.1; extra == "frozen"
154
155
  Requires-Dist: dkist-processing-math==2.2.1; extra == "frozen"
155
156
  Requires-Dist: dkist-processing-pac==3.1.1; extra == "frozen"
156
- Requires-Dist: dkist-processing-visp==5.1.2rc2; extra == "frozen"
157
+ Requires-Dist: dkist-processing-visp==5.2.0rc1; extra == "frozen"
157
158
  Requires-Dist: dkist-service-configuration==4.1.13; extra == "frozen"
158
159
  Requires-Dist: dkist-spectral-lines==3.0.0; extra == "frozen"
159
160
  Requires-Dist: dkist_fits_specifications==4.17.0; extra == "frozen"
@@ -169,7 +170,6 @@ Requires-Dist: globus-sdk==4.2.0; extra == "frozen"
169
170
  Requires-Dist: google-re2==1.1.20251105; extra == "frozen"
170
171
  Requires-Dist: googleapis-common-protos==1.72.0; extra == "frozen"
171
172
  Requires-Dist: gqlclient==1.2.3; extra == "frozen"
172
- Requires-Dist: greenlet==3.3.0; extra == "frozen"
173
173
  Requires-Dist: grpcio==1.76.0; extra == "frozen"
174
174
  Requires-Dist: gunicorn==23.0.0; extra == "frozen"
175
175
  Requires-Dist: h11==0.16.0; extra == "frozen"
@@ -199,7 +199,7 @@ Requires-Dist: markdown-it-py==4.0.0; extra == "frozen"
199
199
  Requires-Dist: marshmallow==3.26.1; extra == "frozen"
200
200
  Requires-Dist: marshmallow-oneofschema==3.2.0; extra == "frozen"
201
201
  Requires-Dist: marshmallow-sqlalchemy==0.28.2; extra == "frozen"
202
- Requires-Dist: matplotlib==3.10.7; extra == "frozen"
202
+ Requires-Dist: matplotlib==3.10.8; extra == "frozen"
203
203
  Requires-Dist: mdit-py-plugins==0.5.0; extra == "frozen"
204
204
  Requires-Dist: mdurl==0.1.2; extra == "frozen"
205
205
  Requires-Dist: methodtools==0.4.7; extra == "frozen"
@@ -210,30 +210,30 @@ Requires-Dist: nbformat==5.10.4; extra == "frozen"
210
210
  Requires-Dist: networkx==3.6.1; extra == "frozen"
211
211
  Requires-Dist: numpy==2.2.5; extra == "frozen"
212
212
  Requires-Dist: object-clerk==1.0.0; extra == "frozen"
213
- Requires-Dist: opentelemetry-api==1.39.0; extra == "frozen"
214
- Requires-Dist: opentelemetry-exporter-otlp==1.39.0; extra == "frozen"
215
- Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.39.0; extra == "frozen"
216
- Requires-Dist: opentelemetry-exporter-otlp-proto-grpc==1.39.0; extra == "frozen"
217
- Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.39.0; extra == "frozen"
218
- Requires-Dist: opentelemetry-instrumentation==0.60b0; extra == "frozen"
219
- Requires-Dist: opentelemetry-instrumentation-aiohttp-client==0.60b0; extra == "frozen"
220
- Requires-Dist: opentelemetry-instrumentation-asgi==0.60b0; extra == "frozen"
221
- Requires-Dist: opentelemetry-instrumentation-botocore==0.60b0; extra == "frozen"
222
- Requires-Dist: opentelemetry-instrumentation-celery==0.60b0; extra == "frozen"
223
- Requires-Dist: opentelemetry-instrumentation-dbapi==0.60b0; extra == "frozen"
224
- Requires-Dist: opentelemetry-instrumentation-fastapi==0.60b0; extra == "frozen"
225
- Requires-Dist: opentelemetry-instrumentation-pika==0.60b0; extra == "frozen"
226
- Requires-Dist: opentelemetry-instrumentation-psycopg2==0.60b0; extra == "frozen"
227
- Requires-Dist: opentelemetry-instrumentation-pymongo==0.60b0; extra == "frozen"
228
- Requires-Dist: opentelemetry-instrumentation-redis==0.60b0; extra == "frozen"
229
- Requires-Dist: opentelemetry-instrumentation-requests==0.60b0; extra == "frozen"
230
- Requires-Dist: opentelemetry-instrumentation-sqlalchemy==0.60b0; extra == "frozen"
231
- Requires-Dist: opentelemetry-instrumentation-system-metrics==0.60b0; extra == "frozen"
213
+ Requires-Dist: opentelemetry-api==1.39.1; extra == "frozen"
214
+ Requires-Dist: opentelemetry-exporter-otlp==1.39.1; extra == "frozen"
215
+ Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.39.1; extra == "frozen"
216
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc==1.39.1; extra == "frozen"
217
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.39.1; extra == "frozen"
218
+ Requires-Dist: opentelemetry-instrumentation==0.60b1; extra == "frozen"
219
+ Requires-Dist: opentelemetry-instrumentation-aiohttp-client==0.60b1; extra == "frozen"
220
+ Requires-Dist: opentelemetry-instrumentation-asgi==0.60b1; extra == "frozen"
221
+ Requires-Dist: opentelemetry-instrumentation-botocore==0.60b1; extra == "frozen"
222
+ Requires-Dist: opentelemetry-instrumentation-celery==0.60b1; extra == "frozen"
223
+ Requires-Dist: opentelemetry-instrumentation-dbapi==0.60b1; extra == "frozen"
224
+ Requires-Dist: opentelemetry-instrumentation-fastapi==0.60b1; extra == "frozen"
225
+ Requires-Dist: opentelemetry-instrumentation-pika==0.60b1; extra == "frozen"
226
+ Requires-Dist: opentelemetry-instrumentation-psycopg2==0.60b1; extra == "frozen"
227
+ Requires-Dist: opentelemetry-instrumentation-pymongo==0.60b1; extra == "frozen"
228
+ Requires-Dist: opentelemetry-instrumentation-redis==0.60b1; extra == "frozen"
229
+ Requires-Dist: opentelemetry-instrumentation-requests==0.60b1; extra == "frozen"
230
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy==0.60b1; extra == "frozen"
231
+ Requires-Dist: opentelemetry-instrumentation-system-metrics==0.60b1; extra == "frozen"
232
232
  Requires-Dist: opentelemetry-propagator-aws-xray==1.0.2; extra == "frozen"
233
- Requires-Dist: opentelemetry-proto==1.39.0; extra == "frozen"
234
- Requires-Dist: opentelemetry-sdk==1.39.0; extra == "frozen"
235
- Requires-Dist: opentelemetry-semantic-conventions==0.60b0; extra == "frozen"
236
- Requires-Dist: opentelemetry-util-http==0.60b0; extra == "frozen"
233
+ Requires-Dist: opentelemetry-proto==1.39.1; extra == "frozen"
234
+ Requires-Dist: opentelemetry-sdk==1.39.1; extra == "frozen"
235
+ Requires-Dist: opentelemetry-semantic-conventions==0.60b1; extra == "frozen"
236
+ Requires-Dist: opentelemetry-util-http==0.60b1; extra == "frozen"
237
237
  Requires-Dist: ordered-set==4.1.0; extra == "frozen"
238
238
  Requires-Dist: packaging==25.0; extra == "frozen"
239
239
  Requires-Dist: pandas==2.3.3; extra == "frozen"
@@ -293,7 +293,7 @@ Requires-Dist: termcolor==3.2.0; extra == "frozen"
293
293
  Requires-Dist: text-unidecode==1.3; extra == "frozen"
294
294
  Requires-Dist: threadpoolctl==3.6.0; extra == "frozen"
295
295
  Requires-Dist: tifffile==2025.10.16; extra == "frozen"
296
- Requires-Dist: tornado==6.5.2; extra == "frozen"
296
+ Requires-Dist: tornado==6.5.3; extra == "frozen"
297
297
  Requires-Dist: tqdm==4.67.1; extra == "frozen"
298
298
  Requires-Dist: traitlets==5.14.3; extra == "frozen"
299
299
  Requires-Dist: typing-inspection==0.4.2; extra == "frozen"
@@ -303,7 +303,7 @@ Requires-Dist: tzlocal==5.3.1; extra == "frozen"
303
303
  Requires-Dist: uc-micro-py==1.0.3; extra == "frozen"
304
304
  Requires-Dist: uncertainties==3.2.3; extra == "frozen"
305
305
  Requires-Dist: universal_pathlib==0.3.7; extra == "frozen"
306
- Requires-Dist: urllib3==2.6.1; extra == "frozen"
306
+ Requires-Dist: urllib3==2.6.2; extra == "frozen"
307
307
  Requires-Dist: vine==5.1.0; extra == "frozen"
308
308
  Requires-Dist: voluptuous==0.15.2; extra == "frozen"
309
309
  Requires-Dist: wcwidth==0.2.14; extra == "frozen"
@@ -0,0 +1,2 @@
1
+ The modification of CRPIX1 and CRPIX2 to account for beam-overlap trimming is now correct for some early (OCP1) ViSP
2
+ data that had their WCS axes switched in the headers.
@@ -0,0 +1 @@
1
+ Add online documentation page for new WavelengthCalibration task.
@@ -0,0 +1 @@
1
+ Add the WavelengthCalibration task, which computes an absolute wavelength solution that is encoded in L1 headers.
@@ -0,0 +1,2 @@
1
+ L1 data now have a correct wavelength solution encoded in their headers. See :doc:`here </wavelength_calibration>`
2
+ for more information.
@@ -0,0 +1 @@
1
+ Update logging lines to print `np.int*` types as plain ints instead of the `__repr__`, which shows the full type.
@@ -5,6 +5,7 @@ from random import randint
5
5
  from typing import Any
6
6
 
7
7
  import astropy.units as u
8
+ from astropy.units import Quantity
8
9
  from dkist_processing_common.models.parameters import ParameterArmIdMixin
9
10
  from dkist_processing_common.models.parameters import ParameterBase
10
11
  from dkist_processing_common.models.parameters import ParameterWavelengthMixin
@@ -200,7 +201,7 @@ class VispParameters(ParameterBase, ParameterWavelengthMixin, ParameterArmIdMixi
200
201
  @property
201
202
  def solar_vignette_dispersion_bounds_fraction(self) -> float:
202
203
  """
203
- Define the ± fraction away from the initial value for bounds on dispersion when fitting the initial vignette signal.
204
+ Define the ± fraction from the initial value for bounds on dispersion when fitting the initial vignette signal.
204
205
 
205
206
  This value should be between 0 and 1. For example, the minimum bound is `init_value * (1 - solar_vignette_dispersion_bounds_fraction)`.
206
207
  """
@@ -230,6 +231,33 @@ class VispParameters(ParameterBase, ParameterWavelengthMixin, ParameterArmIdMixi
230
231
  """Return fractional number of samples required for the RANSAC regressor used to fit the 2D vignette signal."""
231
232
  return self._find_most_recent_past_value("visp_solar_vignette_min_samples")
232
233
 
234
+ @property
235
+ def wavecal_crval_bounds_px(self) -> Quantity:
236
+ """
237
+ Define the bounds (in *pix*) on crval when performing wavecal fitting.
238
+
239
+ The actual bounds on the value of crval are equal to ± the initial dispersion times this number. Note that the
240
+ total range searched by the fitting algorithm will be twice this number (in pixels).
241
+ """
242
+ return self._find_most_recent_past_value("visp_wavecal_crval_bounds_px") * u.pix
243
+
244
+ @property
245
+ def wavecal_dispersion_bounds_fraction(self) -> Quantity:
246
+ """
247
+ Define the ± fraction from the initial value for bounds on dispersion when performing wavecal fitting.
248
+
249
+ This value should be between 0 and 1. For example, the minimum bound is `init_value * (1 - wavecal_dispersion_bounds_fraction)`.
250
+ """
251
+ return self._find_most_recent_past_value("visp_wavecal_dispersion_bounds_fraction")
252
+
253
+ @property
254
+ def wavecal_incident_light_angle_bounds_deg(self) -> Quantity:
255
+ """Define the bounds (in *deg*) on incident_light_angle when performing wavecal fitting."""
256
+ return (
257
+ self._find_most_recent_past_value("visp_wavecal_incident_light_angle_bounds_deg")
258
+ * u.deg
259
+ )
260
+
233
261
  @property
234
262
  def wavecal_camera_lens_parameters(self) -> list[u.Quantity]:
235
263
  r"""
@@ -279,6 +307,20 @@ class VispParameters(ParameterBase, ParameterWavelengthMixin, ParameterArmIdMixi
279
307
  """Define the initial guess for opacity factor in wavecal fits."""
280
308
  return self._find_most_recent_past_value("visp_wavecal_init_opacity_factor")
281
309
 
310
+ @property
311
+ def wavecal_fit_kwargs(self) -> dict[str, Any]:
312
+ """Define extra keyword arguments to pass to the wavelength calibration fitter."""
313
+ doc_dict = self._find_most_recent_past_value("visp_wavecal_fit_kwargs")
314
+ rng_kwarg = dict()
315
+ fitting_method = doc_dict.get("method", False)
316
+ if fitting_method in ["basinhopping", "differential_evolution", "dual_annealing"]:
317
+ rng = randint(1, 1_000_000)
318
+ rng_kwarg["rng"] = rng
319
+
320
+ # The order here allows us to override `rng` in a parameter value
321
+ fit_kwargs = rng_kwarg | doc_dict
322
+ return fit_kwargs
323
+
282
324
  @property
283
325
  def polcal_spatial_median_filter_width_px(self) -> int:
284
326
  """Return the size of the median filter to apply in the spatial dimension to polcal data."""
@@ -2,6 +2,7 @@
2
2
 
3
3
  from enum import Enum
4
4
 
5
+ from dkist_processing_common.models.tags import StemName
5
6
  from dkist_processing_common.models.tags import Tag
6
7
 
7
8
  from dkist_processing_visp.models.task_name import VispTaskName
@@ -63,6 +64,16 @@ class VispTag(Tag):
63
64
  """
64
65
  return cls.format_tag(VispStemName.map_scan, map_scan_num)
65
66
 
67
+ @classmethod
68
+ def task_characteristic_spectra(cls) -> str:
69
+ """Tags intermediate characteristic spectra."""
70
+ return cls.format_tag(StemName.task, VispTaskName.solar_char_spec.value)
71
+
72
+ @classmethod
73
+ def task_wavelength_calibration(cls) -> str:
74
+ """Tags wavelength calibration."""
75
+ return cls.format_tag(StemName.task, VispTaskName.wavelength_calibration.value)
76
+
66
77
  ##################
67
78
  # Composite tags #
68
79
  ##################
@@ -7,3 +7,5 @@ class VispTaskName(str, Enum):
7
7
  """Controlled list of task tag names."""
8
8
 
9
9
  background = "BACKGROUND"
10
+ solar_char_spec = "SOLAR_CHAR_SPEC"
11
+ wavelength_calibration = "WAVELENGTH_CALIBRATION"
@@ -1086,7 +1086,7 @@ class GeometricCalibration(
1086
1086
  "rel_height": self.parameters.geo_zone_rel_height,
1087
1087
  }
1088
1088
  zones = self.compute_line_zones(array, **zone_kwargs)
1089
- logger.info(f"Found {zones = }")
1089
+ logger.info(f"Found zones = {[tuple(int(i) for i in z) for z in zones]}")
1090
1090
  mask = np.zeros(array.shape).astype(bool)
1091
1091
  for z in zones:
1092
1092
  mask[z[0] : z[1], :] = True
@@ -12,6 +12,7 @@ from astropy.time import TimeDelta
12
12
  from dkist_processing_common.codecs.fits import fits_access_decoder
13
13
  from dkist_processing_common.codecs.fits import fits_array_decoder
14
14
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
15
+ from dkist_processing_common.codecs.json import json_decoder
15
16
  from dkist_processing_common.models.fits_access import MetadataKey
16
17
  from dkist_processing_common.models.task_name import TaskName
17
18
  from dkist_processing_common.tasks.mixin.quality import QualityMixin
@@ -42,6 +43,7 @@ class CalibrationCollection:
42
43
  angle: dict
43
44
  state_offset: dict
44
45
  spec_shift: dict
46
+ wavelength_calibration_header: dict
45
47
  demod_matrices: dict | None
46
48
 
47
49
  @cached_property
@@ -176,6 +178,15 @@ class ScienceCalibration(
176
178
  spec_shift_dict = dict()
177
179
  demod_dict = dict() if self.constants.correct_for_polarization else None
178
180
 
181
+ # WaveCal
182
+ #########
183
+ wavecal_header = next(
184
+ self.read(
185
+ tags=[VispTag.intermediate(), VispTag.task_wavelength_calibration()],
186
+ decoder=json_decoder,
187
+ )
188
+ )
189
+
179
190
  for beam in range(1, self.constants.num_beams + 1):
180
191
  for readout_exp_time in self.constants.observe_readout_exp_times:
181
192
  # Dark
@@ -270,6 +281,7 @@ class ScienceCalibration(
270
281
  angle=angle_dict,
271
282
  state_offset=state_offset_dict,
272
283
  spec_shift=spec_shift_dict,
284
+ wavelength_calibration_header=wavecal_header,
273
285
  demod_matrices=demod_dict,
274
286
  )
275
287
 
@@ -761,22 +773,31 @@ class ScienceCalibration(
761
773
  """
762
774
  Update calibrated headers with any information gleaned during science calibration.
763
775
 
764
- Right now all this does is put map scan values in the header.
776
+ #. Apply the wavelength calibration header values
777
+ #. Add map scan keywords
778
+ #. Adjust CRPIX values based on any chopping needed to return only regions where the beams overlap
765
779
 
766
780
  Parameters
767
781
  ----------
768
- header : fits.Header
782
+ header
769
783
  The header to update
770
784
 
771
- map_scan : int
785
+ map_scan
772
786
  Current map scan
773
787
 
788
+ calibrations
789
+ Container of intermediate calibration objects. Used to figure out how much to adjust CRPIX values.
790
+
774
791
  Returns
775
792
  -------
776
793
  fits.Header
777
794
  Updated header
778
795
 
779
796
  """
797
+ # Apply the wavelength calibration
798
+ # This needs to be done prior to adjusting CRPIX values below
799
+ header.update(calibrations.wavelength_calibration_header)
800
+
780
801
  # Update the map scan number
781
802
  header["VSPNMAPS"] = self.constants.num_map_scans
782
803
  header["VSPMAP"] = map_scan
@@ -784,27 +805,51 @@ class ScienceCalibration(
784
805
  # Adjust the CRPIX values if the beam overlap slicing chopped from the start of the array
785
806
  x_slice, y_slice = calibrations.beams_overlap_slice
786
807
 
808
+ # Note: We KNOW that `x_slice` and `y_slice` correspond to the *array* dimensions corresponding to spectral and
809
+ # spatial directions, respectively. Some early ViSP data swap the *WCS* dimensions so that CRPIX1 contains
810
+ # information about the spectral axis, even though the spectral axis is always in the 0th array axis (and thus
811
+ # the second WCS axis because FITS and numpy are backwards; are we confused yet?).
812
+ #
813
+ # We want the adjustment of the CRPIX values to produce accurate WCS information, even if they're associated
814
+ # with the wrong array axes. For this reason we dynamically associate the WCS axis number with `x_slice` and
815
+ # `y_slice` via the `*_wcs_axis_num` properties.
816
+ #
817
+ # To say it differently, we KNOW that `x_slice` always refers to chopping in the spectral dimension, so we need
818
+ # to update the CRPIX associate with the spectral WCS, no matter which WCS axis that is.
819
+
787
820
  # This if catches 0's and Nones
788
821
  if x_slice.start:
789
822
  # .start will only be non-None or 0 if the slice is from the start. In this case we need to update the WCS
790
823
  logger.info(
791
- f"Adjusting CRPIX2 from {header['CRPIX2']} to {header['CRPIX2'] - x_slice.start}"
824
+ f"Adjusting spectral CRPIX{self.spectral_wcs_axis_num} from "
825
+ f"{header[f'CRPIX{self.spectral_wcs_axis_num}']} to {header[f'CRPIX{self.spectral_wcs_axis_num}'] - x_slice.start}"
826
+ )
827
+ header[f"CRPIX{self.spectral_wcs_axis_num}"] = (
828
+ header[f"CRPIX{self.spectral_wcs_axis_num}"] - x_slice.start
792
829
  )
793
- header["CRPIX2"] = header["CRPIX2"] - x_slice.start
794
830
  logger.info(
795
- f"Adjusting CRPIX2A from {header['CRPIX2A']} to {header['CRPIX2A'] - x_slice.start}"
831
+ f"Adjusting spectral CRPIX{self.spectral_wcs_axis_num}A from "
832
+ f"{header[f'CRPIX{self.spectral_wcs_axis_num}A']} to {header[f'CRPIX{self.spectral_wcs_axis_num}A'] - x_slice.start}"
833
+ )
834
+ header[f"CRPIX{self.spectral_wcs_axis_num}A"] = (
835
+ header[f"CRPIX{self.spectral_wcs_axis_num}A"] - x_slice.start
796
836
  )
797
- header["CRPIX2A"] = header["CRPIX2A"] - x_slice.start
798
837
 
799
838
  if y_slice.start:
800
839
  logger.info(
801
- f"Adjusting CRPIX1 from {header['CRPIX1']} to {header['CRPIX1'] - y_slice.start}"
840
+ f"Adjusting spatial CRPIX{self.spatial_wcs_axis_num} from "
841
+ f"{header[f'CRPIX{self.spatial_wcs_axis_num}']} to {header[f'CRPIX{self.spatial_wcs_axis_num}'] - y_slice.start}"
842
+ )
843
+ header[f"CRPIX{self.spatial_wcs_axis_num}"] = (
844
+ header[f"CRPIX{self.spatial_wcs_axis_num}"] - y_slice.start
802
845
  )
803
- header["CRPIX1"] = header["CRPIX1"] - y_slice.start
804
846
  logger.info(
805
- f"Adjusting CRPIX1A from {header['CRPIX1A']} to {header['CRPIX1A'] - y_slice.start}"
847
+ f"Adjusting spatial CRPIX{self.spatial_wcs_axis_num}A from "
848
+ f"{header[f'CRPIX{self.spatial_wcs_axis_num}A']} to {header[f'CRPIX{self.spatial_wcs_axis_num}A'] - y_slice.start}"
849
+ )
850
+ header[f"CRPIX{self.spatial_wcs_axis_num}A"] = (
851
+ header[f"CRPIX{self.spatial_wcs_axis_num}A"] - y_slice.start
806
852
  )
807
- header["CRPIX1A"] = header["CRPIX1A"] - y_slice.start
808
853
 
809
854
  return header
810
855
 
@@ -900,3 +945,35 @@ class ScienceCalibration(
900
945
 
901
946
  filename = next(self.read(tags=tags))
902
947
  logger.info(f"Wrote intermediate file for {tags = } to {filename}")
948
+
949
+ @cached_property
950
+ def spectral_wcs_axis_num(self) -> int:
951
+ """
952
+ Return the WCS axis number corresponding to wavelength.
953
+
954
+ We need to check this dynamically because some early ViSP data got the WCS backward w.r.t. the array dimensions.
955
+ """
956
+ try:
957
+ spectral_axis_num = next(
958
+ (i for i in range(1, 4) if getattr(self.constants, f"axis_{i}_type") == "AWAV")
959
+ )
960
+ except StopIteration as e:
961
+ raise ValueError("Could not find WCS axis with type AWAV") from e
962
+
963
+ return spectral_axis_num
964
+
965
+ @cached_property
966
+ def spatial_wcs_axis_num(self) -> int:
967
+ """
968
+ Return the WCS axis number corresponding to Helioprojective latitude.
969
+
970
+ We need to check this dynamically because some early ViSP data got the WCS backward w.r.t. the array dimensions.
971
+ """
972
+ try:
973
+ spatial_axis_num = next(
974
+ (i for i in range(1, 4) if getattr(self.constants, f"axis_{i}_type") == "HPLT-TAN")
975
+ )
976
+ except StopIteration as e:
977
+ raise ValueError("Cound not find WCS axis with type HPLT-TAN") from e
978
+
979
+ return spatial_axis_num