dkist-processing-visp 5.8.0rc1__tar.gz → 5.8.2__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 (126) hide show
  1. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/CHANGELOG.rst +27 -0
  2. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/PKG-INFO +37 -37
  3. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/constants.py +21 -4
  4. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/fits_access.py +1 -0
  5. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/tags.py +11 -0
  6. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/task_name.py +1 -0
  7. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/time.py +41 -0
  8. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/visp_l0_fits_access.py +4 -0
  9. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/assemble_movie.py +9 -2
  10. dkist_processing_visp-5.8.2/dkist_processing_visp/tasks/make_movie_frames.py +351 -0
  11. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/parse.py +9 -6
  12. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/solar.py +290 -119
  13. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/wavelength_calibration.py +14 -2
  14. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/conftest.py +11 -4
  15. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/header_models.py +11 -0
  16. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/local_trial_workflows/local_trial_helpers.py +23 -14
  17. dkist_processing_visp-5.8.2/dkist_processing_visp/tests/test_assemble_movie.py +135 -0
  18. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_fits_access.py +4 -0
  19. dkist_processing_visp-5.8.2/dkist_processing_visp/tests/test_make_movie_frames.py +245 -0
  20. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_parse.py +30 -14
  21. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_solar.py +61 -18
  22. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_visp_constants.py +47 -1
  23. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_wavelength_calibration.py +36 -3
  24. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp.egg-info/PKG-INFO +37 -37
  25. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp.egg-info/SOURCES.txt +0 -1
  26. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp.egg-info/requires.txt +36 -36
  27. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp.egg-info/scm_file_list.json +0 -1
  28. dkist_processing_visp-5.8.2/dkist_processing_visp.egg-info/scm_version.json +8 -0
  29. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/pyproject.toml +38 -38
  30. dkist_processing_visp-5.8.0rc1/changelog/328.misc.rst +0 -1
  31. dkist_processing_visp-5.8.0rc1/dkist_processing_visp/tasks/make_movie_frames.py +0 -160
  32. dkist_processing_visp-5.8.0rc1/dkist_processing_visp/tests/test_assemble_movie.py +0 -62
  33. dkist_processing_visp-5.8.0rc1/dkist_processing_visp/tests/test_make_movie_frames.py +0 -61
  34. dkist_processing_visp-5.8.0rc1/dkist_processing_visp.egg-info/scm_version.json +0 -8
  35. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/.gitignore +0 -0
  36. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/.pre-commit-config.yaml +0 -0
  37. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/.readthedocs.yml +0 -0
  38. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/.rovodev/.review-agent.md +0 -0
  39. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/.snyk +0 -0
  40. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/README.rst +0 -0
  41. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/SCIENCE_CHANGELOG.rst +0 -0
  42. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/bitbucket-pipelines.yml +0 -0
  43. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/changelog/.gitempty +0 -0
  44. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/__init__.py +0 -0
  45. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/config.py +0 -0
  46. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/fonts/Lato-Regular.ttf +0 -0
  47. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/__init__.py +0 -0
  48. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/dataset_extras.py +0 -0
  49. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/metric_code.py +0 -0
  50. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/models/parameters.py +0 -0
  51. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/__init__.py +0 -0
  52. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/map_repeats.py +0 -0
  53. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/modulator_states.py +0 -0
  54. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/polarimeter_mode.py +0 -0
  55. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/raster_step.py +0 -0
  56. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/spectrograph_configuration.py +0 -0
  57. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/parsers/visp_l1_fits_access.py +0 -0
  58. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/__init__.py +0 -0
  59. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/background_light.py +0 -0
  60. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/dark.py +0 -0
  61. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/geometric.py +0 -0
  62. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/instrument_polarization.py +0 -0
  63. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/l1_output_data.py +0 -0
  64. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/lamp.py +0 -0
  65. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/mixin/__init__.py +0 -0
  66. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/mixin/beam_access.py +0 -0
  67. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/mixin/corrections.py +0 -0
  68. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/mixin/downsample.py +0 -0
  69. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/polcal_as_science.py +0 -0
  70. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/quality_metrics.py +0 -0
  71. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/science.py +0 -0
  72. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/visp_base.py +0 -0
  73. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/write_dataset_extras.py +0 -0
  74. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tasks/write_l1.py +0 -0
  75. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/README.rst +0 -0
  76. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/__init__.py +0 -0
  77. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/local_trial_workflows/__init__.py +0 -0
  78. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/local_trial_workflows/l0_cals_only.py +0 -0
  79. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/local_trial_workflows/l0_polcals_as_science.py +0 -0
  80. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/local_trial_workflows/l0_solar_gain_as_science.py +0 -0
  81. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/local_trial_workflows/l0_to_l1.py +0 -0
  82. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_assemble_quality.py +0 -0
  83. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_background_light.py +0 -0
  84. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_dark.py +0 -0
  85. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_downsample.py +0 -0
  86. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_geometric.py +0 -0
  87. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_instrument_polarization.py +0 -0
  88. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_lamp.py +0 -0
  89. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_map_repeats.py +0 -0
  90. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_parameters.py +0 -0
  91. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_polcal_as_science.py +0 -0
  92. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_quality.py +0 -0
  93. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_science.py +0 -0
  94. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_trial_create_quality_report.py +0 -0
  95. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_visp_base.py +0 -0
  96. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_workflows.py +0 -0
  97. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_write_dataset_extras.py +0 -0
  98. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/tests/test_write_l1.py +0 -0
  99. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/workflows/__init__.py +0 -0
  100. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/workflows/l0_processing.py +0 -0
  101. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/workflows/single_task_workflows.py +0 -0
  102. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp/workflows/trial_workflows.py +0 -0
  103. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp.egg-info/dependency_links.txt +0 -0
  104. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/dkist_processing_visp.egg-info/top_level.txt +0 -0
  105. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/Makefile +0 -0
  106. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/background_light.rst +0 -0
  107. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/changelog.rst +0 -0
  108. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/conf.py +0 -0
  109. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/dataset_extras.rst +0 -0
  110. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/gain_correction.rst +0 -0
  111. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/geometric.rst +0 -0
  112. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/index.rst +0 -0
  113. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/l0_to_l1_visp.rst +0 -0
  114. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/l0_to_l1_visp_full-trial.rst +0 -0
  115. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/landing_page.rst +0 -0
  116. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/make.bat +0 -0
  117. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/polarization_calibration.rst +0 -0
  118. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/requirements.txt +0 -0
  119. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/requirements_table.rst +0 -0
  120. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/science_calibration.rst +0 -0
  121. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/scientific_changelog.rst +0 -0
  122. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/docs/wavelength_calibration.rst +0 -0
  123. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/licenses/LICENSE.rst +0 -0
  124. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/science_towncrier.sh +0 -0
  125. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/setup.cfg +0 -0
  126. {dkist_processing_visp-5.8.0rc1 → dkist_processing_visp-5.8.2}/towncrier_science.toml +0 -0
@@ -1,3 +1,30 @@
1
+ v5.8.2 (2026-09-04)
2
+ ===================
3
+
4
+ Bugfixes
5
+ --------
6
+
7
+ - Update movie generation for "sit'n'stare" datasets to avoid out-of-memory failures. Movies for sit'n'stare observations (when the slit doesn't move) are now displayed with time on the "spatial" axis; each column is the wavelength-integrated signal of a single slit observation. Genuine spatial raster scans, of any polarization mode, are unaffected and continue to use the existing algorithm. (`#329 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/329>`__)
8
+
9
+
10
+ v5.8.1 (2026-08-28)
11
+ ===================
12
+
13
+ Bugfixes
14
+ --------
15
+
16
+ - Allow multiple solar gain observations to contribute to solar gain calibration while using only the observation nearest in time to the science frames for wavelength calibration. (`#332 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/332>`__)
17
+
18
+
19
+ v5.8.0 (2026-08-25)
20
+ ===================
21
+
22
+ Misc
23
+ ----
24
+
25
+ - Convert wavelength calibration quality metric generation to the new storage-based framework. (`#328 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/328>`__)
26
+
27
+
1
28
  v5.7.28 (2026-08-14)
2
29
  ====================
3
30
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-processing-visp
3
- Version: 5.8.0rc1
3
+ Version: 5.8.2
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.13
14
14
  Requires-Python: >=3.13
15
15
  Description-Content-Type: text/x-rst
16
- Requires-Dist: dkist-processing-common==14.4.0rc1
16
+ Requires-Dist: dkist-processing-common==14.4.0
17
17
  Requires-Dist: dkist-processing-math==2.2.3
18
18
  Requires-Dist: dkist-processing-pac==3.1.2
19
19
  Requires-Dist: dkist-header-validator==5.4.0
@@ -84,11 +84,11 @@ Requires-Dist: aiohttp==3.14.3; extra == "frozen"
84
84
  Requires-Dist: aiosignal==1.4.0; extra == "frozen"
85
85
  Requires-Dist: aiosmtplib==5.1.2; extra == "frozen"
86
86
  Requires-Dist: aiosqlite==0.22.1; extra == "frozen"
87
- Requires-Dist: alembic==1.19.1; extra == "frozen"
87
+ Requires-Dist: alembic==1.19.2; extra == "frozen"
88
88
  Requires-Dist: amqp==5.3.1; extra == "frozen"
89
89
  Requires-Dist: annotated-doc==0.0.5; extra == "frozen"
90
90
  Requires-Dist: annotated-types==0.8.0; extra == "frozen"
91
- Requires-Dist: anyio==4.14.2; extra == "frozen"
91
+ Requires-Dist: anyio==4.15.0; extra == "frozen"
92
92
  Requires-Dist: apache-airflow==3.3.1; extra == "frozen"
93
93
  Requires-Dist: apache-airflow-core==3.3.1; extra == "frozen"
94
94
  Requires-Dist: apache-airflow-providers-celery==3.23.1; extra == "frozen"
@@ -109,7 +109,7 @@ Requires-Dist: asdf_standard==1.5.0; extra == "frozen"
109
109
  Requires-Dist: asgiref==3.12.1; extra == "frozen"
110
110
  Requires-Dist: asteval==1.0.10; extra == "frozen"
111
111
  Requires-Dist: astropy==7.0.2; extra == "frozen"
112
- Requires-Dist: astropy-iers-data==0.2026.8.24.0.24.29; extra == "frozen"
112
+ Requires-Dist: astropy-iers-data==0.2026.8.31.0.57.9; extra == "frozen"
113
113
  Requires-Dist: asttokens==3.0.2; extra == "frozen"
114
114
  Requires-Dist: async-lru==2.3.0; extra == "frozen"
115
115
  Requires-Dist: asyncpg==0.31.0; extra == "frozen"
@@ -118,35 +118,36 @@ Requires-Dist: babel==2.18.0; extra == "frozen"
118
118
  Requires-Dist: beautifulsoup4==4.15.0; extra == "frozen"
119
119
  Requires-Dist: billiard==4.2.4; extra == "frozen"
120
120
  Requires-Dist: bleach==6.4.0; extra == "frozen"
121
- Requires-Dist: boto3==1.43.79; extra == "frozen"
122
- Requires-Dist: botocore==1.43.79; extra == "frozen"
123
- Requires-Dist: cachetools==7.1.7; extra == "frozen"
121
+ Requires-Dist: boto3==1.43.88; extra == "frozen"
122
+ Requires-Dist: botocore==1.43.88; extra == "frozen"
123
+ Requires-Dist: cachetools==7.1.8; extra == "frozen"
124
124
  Requires-Dist: cadwyn==7.0.0; extra == "frozen"
125
125
  Requires-Dist: celery==5.6.3; extra == "frozen"
126
126
  Requires-Dist: certifi==2026.7.22; extra == "frozen"
127
127
  Requires-Dist: cffi==2.1.1; extra == "frozen"
128
128
  Requires-Dist: charset-normalizer==3.5.1; extra == "frozen"
129
- Requires-Dist: click==8.4.2; extra == "frozen"
129
+ Requires-Dist: click==8.5.0; extra == "frozen"
130
130
  Requires-Dist: click-didyoumean==0.3.1; extra == "frozen"
131
131
  Requires-Dist: click-plugins==1.1.1.2; extra == "frozen"
132
132
  Requires-Dist: click-repl==0.3.0; extra == "frozen"
133
+ Requires-Dist: cloudpickle==3.1.2; extra == "frozen"
133
134
  Requires-Dist: colorlog==6.12.0; extra == "frozen"
134
135
  Requires-Dist: comm==0.2.3; extra == "frozen"
135
136
  Requires-Dist: contourpy==1.3.3; extra == "frozen"
136
137
  Requires-Dist: cron_descriptor==2.1.0; extra == "frozen"
137
138
  Requires-Dist: croniter==6.2.4; extra == "frozen"
138
- Requires-Dist: cryptography==50.0.0; extra == "frozen"
139
+ Requires-Dist: cryptography==50.0.1; extra == "frozen"
139
140
  Requires-Dist: cycler==0.12.1; extra == "frozen"
140
141
  Requires-Dist: debugpy==1.8.21; extra == "frozen"
141
142
  Requires-Dist: decorator==5.3.1; extra == "frozen"
142
143
  Requires-Dist: defusedxml==0.7.1; extra == "frozen"
143
144
  Requires-Dist: dill==0.4.1; extra == "frozen"
144
145
  Requires-Dist: dkist-header-validator==5.4.0; extra == "frozen"
145
- Requires-Dist: dkist-processing-common==14.4.0rc1; extra == "frozen"
146
+ Requires-Dist: dkist-processing-common==14.4.0; extra == "frozen"
146
147
  Requires-Dist: dkist-processing-core==7.5.0; extra == "frozen"
147
148
  Requires-Dist: dkist-processing-math==2.2.3; extra == "frozen"
148
149
  Requires-Dist: dkist-processing-pac==3.1.2; extra == "frozen"
149
- Requires-Dist: dkist-processing-visp==5.8.0rc1; extra == "frozen"
150
+ Requires-Dist: dkist-processing-visp==5.8.2; extra == "frozen"
150
151
  Requires-Dist: dkist-service-configuration==4.3.0; extra == "frozen"
151
152
  Requires-Dist: dkist-spectral-lines==3.0.1; extra == "frozen"
152
153
  Requires-Dist: dkist_fits_specifications==4.28.1; extra == "frozen"
@@ -157,16 +158,16 @@ Requires-Dist: fastapi==0.136.3; extra == "frozen"
157
158
  Requires-Dist: fastapi-cli==0.0.32; extra == "frozen"
158
159
  Requires-Dist: fastjsonschema==2.22.2; extra == "frozen"
159
160
  Requires-Dist: flower==2.1.0; extra == "frozen"
160
- Requires-Dist: fonttools==4.63.0; extra == "frozen"
161
+ Requires-Dist: fonttools==4.64.0; extra == "frozen"
161
162
  Requires-Dist: fqdn==1.5.1; extra == "frozen"
162
163
  Requires-Dist: frozenlist==1.8.0; extra == "frozen"
163
164
  Requires-Dist: fsspec==2026.7.0; extra == "frozen"
164
165
  Requires-Dist: globus-sdk==4.9.0; extra == "frozen"
165
- Requires-Dist: googleapis-common-protos==1.75.1; extra == "frozen"
166
+ Requires-Dist: googleapis-common-protos==1.75.3; extra == "frozen"
166
167
  Requires-Dist: gqlclient==2.0.0; extra == "frozen"
167
168
  Requires-Dist: greenback==1.3.0; extra == "frozen"
168
169
  Requires-Dist: greenlet==3.5.5; extra == "frozen"
169
- Requires-Dist: grpcio==1.83.0; extra == "frozen"
170
+ Requires-Dist: grpcio==1.83.1; extra == "frozen"
170
171
  Requires-Dist: h11==0.16.0; extra == "frozen"
171
172
  Requires-Dist: httpcore==1.0.9; extra == "frozen"
172
173
  Requires-Dist: httptools==0.8.0; extra == "frozen"
@@ -174,36 +175,36 @@ Requires-Dist: httpx==0.28.1; extra == "frozen"
174
175
  Requires-Dist: humanize==4.16.0; extra == "frozen"
175
176
  Requires-Dist: idna==3.19; extra == "frozen"
176
177
  Requires-Dist: imageio-ffmpeg==0.6.0; extra == "frozen"
177
- Requires-Dist: importlib_metadata==9.0.0; extra == "frozen"
178
+ Requires-Dist: importlib_metadata==9.0.1; extra == "frozen"
178
179
  Requires-Dist: ipykernel==7.3.0; extra == "frozen"
179
- Requires-Dist: ipython==9.16.1; extra == "frozen"
180
+ Requires-Dist: ipython==9.17.1; extra == "frozen"
180
181
  Requires-Dist: ipython_pygments_lexers==1.1.1; extra == "frozen"
181
182
  Requires-Dist: isoduration==20.11.0; extra == "frozen"
182
183
  Requires-Dist: itsdangerous==2.2.0; extra == "frozen"
183
184
  Requires-Dist: jedi==0.20.0; extra == "frozen"
184
185
  Requires-Dist: jmespath==1.1.0; extra == "frozen"
185
- Requires-Dist: joblib==1.5.3; extra == "frozen"
186
+ Requires-Dist: joblib==1.6.0; extra == "frozen"
186
187
  Requires-Dist: json5==0.15.0; extra == "frozen"
187
188
  Requires-Dist: jsonpointer==3.1.1; extra == "frozen"
188
189
  Requires-Dist: jsonschema==4.26.0; extra == "frozen"
189
190
  Requires-Dist: jsonschema-specifications==2025.9.1; extra == "frozen"
190
191
  Requires-Dist: jupyter-events==0.12.1; extra == "frozen"
191
192
  Requires-Dist: jupyter-lsp==2.3.1; extra == "frozen"
192
- Requires-Dist: jupyter_builder==1.2.2; extra == "frozen"
193
- Requires-Dist: jupyter_client==8.9.1; extra == "frozen"
193
+ Requires-Dist: jupyter_builder==1.2.3; extra == "frozen"
194
+ Requires-Dist: jupyter_client==8.10.0; extra == "frozen"
194
195
  Requires-Dist: jupyter_core==5.9.1; extra == "frozen"
195
- Requires-Dist: jupyter_server==2.20.0; extra == "frozen"
196
+ Requires-Dist: jupyter_server==2.21.0; extra == "frozen"
196
197
  Requires-Dist: jupyter_server_terminals==0.5.4; extra == "frozen"
197
198
  Requires-Dist: jupyterlab==4.6.3; extra == "frozen"
198
199
  Requires-Dist: jupyterlab_pygments==0.3.0; extra == "frozen"
199
200
  Requires-Dist: jupyterlab_server==2.28.0; extra == "frozen"
200
- Requires-Dist: kiwisolver==1.5.0; extra == "frozen"
201
+ Requires-Dist: kiwisolver==1.5.1; extra == "frozen"
201
202
  Requires-Dist: kombu==5.6.2; extra == "frozen"
202
203
  Requires-Dist: lark==1.3.1; extra == "frozen"
203
204
  Requires-Dist: lazy-loader==0.5; extra == "frozen"
204
205
  Requires-Dist: lazy-object-proxy==1.12.0; extra == "frozen"
205
206
  Requires-Dist: libcst==1.9.0; extra == "frozen"
206
- Requires-Dist: linkify-it-py==2.1.1; extra == "frozen"
207
+ Requires-Dist: linkify-it-py==2.2.0; extra == "frozen"
207
208
  Requires-Dist: lmfit==1.3.4; extra == "frozen"
208
209
  Requires-Dist: lockfile==0.12.2; extra == "frozen"
209
210
  Requires-Dist: loguru==0.7.3; extra == "frozen"
@@ -264,27 +265,27 @@ Requires-Dist: pexpect==4.9.0; extra == "frozen"
264
265
  Requires-Dist: pika==1.4.4; extra == "frozen"
265
266
  Requires-Dist: pillow==10.4.0; extra == "frozen"
266
267
  Requires-Dist: pip==26.2.1; extra == "frozen"
267
- Requires-Dist: platformdirs==4.11.4; extra == "frozen"
268
+ Requires-Dist: platformdirs==4.11.7; extra == "frozen"
268
269
  Requires-Dist: pluggy==1.6.0; extra == "frozen"
269
270
  Requires-Dist: pooch==1.9.0; extra == "frozen"
270
271
  Requires-Dist: proglog==0.1.12; extra == "frozen"
271
272
  Requires-Dist: prometheus_client==0.26.0; extra == "frozen"
272
273
  Requires-Dist: prompt_toolkit==3.0.53; extra == "frozen"
273
274
  Requires-Dist: propcache==0.5.2; extra == "frozen"
274
- Requires-Dist: protobuf==7.36.0; extra == "frozen"
275
+ Requires-Dist: protobuf==7.36.1; extra == "frozen"
275
276
  Requires-Dist: psutil==7.2.2; extra == "frozen"
276
- Requires-Dist: psycopg==3.3.4; extra == "frozen"
277
- Requires-Dist: psycopg-binary==3.3.4; extra == "frozen"
277
+ Requires-Dist: psycopg==3.3.5; extra == "frozen"
278
+ Requires-Dist: psycopg-binary==3.3.5; extra == "frozen"
278
279
  Requires-Dist: psycopg2-binary==2.9.12; extra == "frozen"
279
280
  Requires-Dist: ptyprocess==0.7.0; extra == "frozen"
280
281
  Requires-Dist: pure_eval==0.2.3; extra == "frozen"
281
282
  Requires-Dist: pycparser==3.0; extra == "frozen"
282
- Requires-Dist: pydantic==2.13.4; extra == "frozen"
283
+ Requires-Dist: pydantic==2.13.5; extra == "frozen"
283
284
  Requires-Dist: pydantic-extra-types==2.11.1; extra == "frozen"
284
285
  Requires-Dist: pydantic-settings==2.15.0; extra == "frozen"
285
- Requires-Dist: pydantic_core==2.46.4; extra == "frozen"
286
+ Requires-Dist: pydantic_core==2.46.5; extra == "frozen"
286
287
  Requires-Dist: pyerfa==2.0.1.5; extra == "frozen"
287
- Requires-Dist: pygtrie==2.5.0; extra == "frozen"
288
+ Requires-Dist: pygtrie==2.6.1; extra == "frozen"
288
289
  Requires-Dist: pyparsing==3.3.2; extra == "frozen"
289
290
  Requires-Dist: python-daemon==3.1.2; extra == "frozen"
290
291
  Requires-Dist: python-dateutil==2.9.0.post0; extra == "frozen"
@@ -302,7 +303,7 @@ Requires-Dist: rfc3986-validator==0.1.1; extra == "frozen"
302
303
  Requires-Dist: rfc3987-syntax==1.1.0; extra == "frozen"
303
304
  Requires-Dist: rich==15.0.0; extra == "frozen"
304
305
  Requires-Dist: rich-argparse==1.8.0; extra == "frozen"
305
- Requires-Dist: rich-toolkit==0.20.3; extra == "frozen"
306
+ Requires-Dist: rich-toolkit==0.20.4; extra == "frozen"
306
307
  Requires-Dist: rpds-py==2026.6.3; extra == "frozen"
307
308
  Requires-Dist: s3transfer==0.19.2; extra == "frozen"
308
309
  Requires-Dist: scikit-image==0.25.2; extra == "frozen"
@@ -334,12 +335,11 @@ Requires-Dist: tinycss2==1.5.1; extra == "frozen"
334
335
  Requires-Dist: tornado==6.5.8; extra == "frozen"
335
336
  Requires-Dist: tqdm==4.70.0; extra == "frozen"
336
337
  Requires-Dist: traitlets==5.16.1; extra == "frozen"
337
- Requires-Dist: typer==0.27.1; extra == "frozen"
338
+ Requires-Dist: typer==0.27.2; extra == "frozen"
338
339
  Requires-Dist: typing-inspection==0.4.4; extra == "frozen"
339
340
  Requires-Dist: typing_extensions==4.16.0; extra == "frozen"
340
341
  Requires-Dist: tzdata==2026.3; extra == "frozen"
341
342
  Requires-Dist: tzlocal==5.4.4; extra == "frozen"
342
- Requires-Dist: uc-micro-py==2.0.0; extra == "frozen"
343
343
  Requires-Dist: uncertainties==3.2.3; extra == "frozen"
344
344
  Requires-Dist: universal_pathlib==0.3.10; extra == "frozen"
345
345
  Requires-Dist: uri-template==1.3.0; extra == "frozen"
@@ -350,13 +350,13 @@ Requires-Dist: uvloop==0.22.1; extra == "frozen"
350
350
  Requires-Dist: vine==5.1.0; extra == "frozen"
351
351
  Requires-Dist: voluptuous==0.16.0; extra == "frozen"
352
352
  Requires-Dist: watchfiles==1.2.0; extra == "frozen"
353
- Requires-Dist: wcwidth==0.8.2; extra == "frozen"
353
+ Requires-Dist: wcwidth==0.8.3; extra == "frozen"
354
354
  Requires-Dist: webcolors==25.10.0; extra == "frozen"
355
355
  Requires-Dist: webencodings==0.6.1; extra == "frozen"
356
- Requires-Dist: websocket-client==1.9.0; extra == "frozen"
357
- Requires-Dist: websockets==17.0.1; extra == "frozen"
356
+ Requires-Dist: websocket-client==1.9.2; extra == "frozen"
357
+ Requires-Dist: websockets==17.1; extra == "frozen"
358
358
  Requires-Dist: wirerope==1.0.0; extra == "frozen"
359
- Requires-Dist: wrapt==2.3.0; extra == "frozen"
359
+ Requires-Dist: wrapt==2.4.0; extra == "frozen"
360
360
  Requires-Dist: yamale==6.1.0; extra == "frozen"
361
361
  Requires-Dist: yarl==1.24.5; extra == "frozen"
362
362
  Requires-Dist: zipp==4.1.0; extra == "frozen"
@@ -28,12 +28,13 @@ class VispBudName(Enum):
28
28
  incident_light_angle_deg = "INCIDENT_LIGHT_ANGLE_DEG"
29
29
  reflected_light_angle_deg = "REFLECTED_LIGHT_ANGLE_DEG"
30
30
  grating_constant_inverse_mm = "GRATING_CONSTANT_INVERSE_MM"
31
- solar_gain_ip_start_time = "SOLAR_GAIN_IP_START_TIME"
31
+ solar_gain_ip_start_times = "SOLAR_GAIN_IP_START_TIMES"
32
32
  axis_1_type = "AXIS_1_TYPE"
33
33
  axis_2_type = "AXIS_2_TYPE"
34
34
  axis_3_type = "AXIS_3_TYPE"
35
35
  dark_readout_exp_time_picky_bud = "DARK_READOUT_EXP_TIME_PICKY_BUD"
36
36
  dark_readout_to_total_exp_times_lookup = "DARK_READOUT_TO_TOTAL_EXP_TIMES_LOOKUP"
37
+ slit_velocity_mm_per_s = "SLIT_VELOCITY_MM_PER_S"
37
38
 
38
39
 
39
40
  class VispConstants(ConstantsBase):
@@ -171,9 +172,9 @@ class VispConstants(ConstantsBase):
171
172
  return self._db_dict[VispBudName.grating_constant_inverse_mm] / u.mm
172
173
 
173
174
  @property
174
- def solar_gain_ip_start_time(self) -> str:
175
- """Return the start time of the SOLAR GAIN Instrument Program."""
176
- return self._db_dict[VispBudName.solar_gain_ip_start_time]
175
+ def solar_gain_ip_start_times(self) -> list[str]:
176
+ """Return the start times of the SOLAR GAIN Instrument Programs."""
177
+ return list(self._db_dict[VispBudName.solar_gain_ip_start_times])
177
178
 
178
179
  @property
179
180
  def axis_1_type(self) -> str:
@@ -196,3 +197,19 @@ class VispConstants(ConstantsBase):
196
197
  raw_return = self._db_dict[VispBudName.dark_readout_to_total_exp_times_lookup]
197
198
  # convert JSON string keys back to float
198
199
  return {float(k): v for k, v in raw_return.items()}
200
+
201
+ @property
202
+ def slit_velocity_mm_per_s(self) -> float:
203
+ """Return observation slit velocity [mm/s]."""
204
+ return self._db_dict[VispBudName.slit_velocity_mm_per_s.value]
205
+
206
+ @property
207
+ def is_sit_n_stare(self) -> bool:
208
+ """
209
+ Return True if the data were acquired in the intensity-only, no-slit-motion "sit'n'stare" mode.
210
+
211
+ The data are sit'n'stare if they were acquired in intensity mode with a slit velocity of
212
+ exactly zero (the slit never moved).
213
+ """
214
+ is_slit_stationary = self.slit_velocity_mm_per_s == 0.0
215
+ return self.polarimeter_mode == "observe_intensity" and is_slit_stationary
@@ -15,6 +15,7 @@ class VispMetadataKey(StrEnum):
15
15
  grating_angle_deg = "VSPGRTAN"
16
16
  arm_position_deg = "VSPARMPS"
17
17
  grating_constant_inverse_mm = "VSPGRTCN"
18
+ slit_velocity_mm_per_s = "VSPSLTSV"
18
19
  axis_1_type = "CTYPE1"
19
20
  axis_2_type = "CTYPE2"
20
21
  axis_3_type = "CTYPE3"
@@ -16,6 +16,7 @@ class VispStemName(str, Enum):
16
16
  modstate = "MODSTATE"
17
17
  file_id = "FILE_ID"
18
18
  map_scan = "MAP_SCAN"
19
+ solar_gain_ip_start_time = "SOLAR_GAIN_IP_START_TIME"
19
20
 
20
21
 
21
22
  class VispTag(Tag):
@@ -64,11 +65,21 @@ class VispTag(Tag):
64
65
  """
65
66
  return cls.format_tag(VispStemName.map_scan, map_scan_num)
66
67
 
68
+ @classmethod
69
+ def solar_gain_ip_start_time(cls, ip_start_time: str) -> str:
70
+ """Tag a solar gain frame or intermediate by its IP start time."""
71
+ return cls.format_tag(VispStemName.solar_gain_ip_start_time, ip_start_time)
72
+
67
73
  @classmethod
68
74
  def task_characteristic_spectra(cls) -> str:
69
75
  """Tags intermediate characteristic spectra."""
70
76
  return cls.format_tag(StemName.task, VispTaskName.solar_char_spec.value)
71
77
 
78
+ @classmethod
79
+ def task_wavecal_characteristic_spectra(cls) -> str:
80
+ """Tag the characteristic spectra derived for wavelength calibration."""
81
+ return cls.format_tag(StemName.task, VispTaskName.wavecal_solar_char_spec.value)
82
+
72
83
  @classmethod
73
84
  def task_wavelength_calibration(cls) -> str:
74
85
  """Tags wavelength calibration."""
@@ -8,4 +8,5 @@ class VispTaskName(str, Enum):
8
8
 
9
9
  background = "BACKGROUND"
10
10
  solar_char_spec = "SOLAR_CHAR_SPEC"
11
+ wavecal_solar_char_spec = "WAVECAL_SOLAR_CHAR_SPEC"
11
12
  wavelength_calibration = "WAVELENGTH_CALIBRATION"
@@ -13,10 +13,15 @@ from dkist_processing_common.models.flower_pot import SpilledDirt
13
13
  from dkist_processing_common.models.flower_pot import Thorn
14
14
  from dkist_processing_common.models.tags import EXP_TIME_ROUND_DIGITS
15
15
  from dkist_processing_common.models.task_name import TaskName
16
+ from dkist_processing_common.parsers.single_value_single_key_flower import (
17
+ SingleValueSingleKeyFlower,
18
+ )
19
+ from dkist_processing_common.parsers.task import parse_header_ip_task_with_gains
16
20
  from dkist_processing_common.parsers.task import passthrough_header_ip_task
17
21
  from dkist_processing_common.parsers.time import TaskDatetimeBudBase
18
22
 
19
23
  from dkist_processing_visp.models.constants import VispBudName
24
+ from dkist_processing_visp.models.tags import VispStemName
20
25
  from dkist_processing_visp.parsers.visp_l0_fits_access import VispL0FitsAccess
21
26
 
22
27
 
@@ -133,6 +138,42 @@ class DarkReadoutExpTimePickyBud(ListStem):
133
138
  return Thorn
134
139
 
135
140
 
141
+ class SolarGainIpStartTimesBud(SetStem):
142
+ """Collect the unique IP start times from all solar gain observations."""
143
+
144
+ def __init__(self):
145
+ super().__init__(stem_name=VispBudName.solar_gain_ip_start_times.value)
146
+ self.metadata_key = MetadataKey.ip_start_time.name
147
+
148
+ def setter(self, fits_obj: VispL0FitsAccess) -> str | Type[SpilledDirt]:
149
+ """Collect start times only from frames parsed as solar gains."""
150
+ task = parse_header_ip_task_with_gains(fits_obj)
151
+ if task.casefold() == TaskName.solar_gain.value.casefold():
152
+ return getattr(fits_obj, self.metadata_key)
153
+ return SpilledDirt
154
+
155
+ def getter(self) -> tuple[str, ...]:
156
+ """Return the unique start times in chronological order."""
157
+ return tuple(sorted(self.value_set))
158
+
159
+
160
+ class SolarGainIpStartTimeFlower(SingleValueSingleKeyFlower):
161
+ """Tag each input solar gain frame with its IP start time."""
162
+
163
+ def __init__(self):
164
+ super().__init__(
165
+ tag_stem_name=VispStemName.solar_gain_ip_start_time,
166
+ metadata_key=MetadataKey.ip_start_time,
167
+ )
168
+
169
+ def setter(self, fits_obj: VispL0FitsAccess) -> str | Type[SpilledDirt]:
170
+ """Apply the tag only to frames parsed as solar gains."""
171
+ task = parse_header_ip_task_with_gains(fits_obj)
172
+ if task.casefold() == TaskName.solar_gain.value.casefold():
173
+ return super().setter(fits_obj)
174
+ return SpilledDirt
175
+
176
+
136
177
  class TaskDateEndBud(TaskDatetimeBudBase):
137
178
  """Class for the date end task Bud."""
138
179
 
@@ -54,6 +54,10 @@ class VispL0FitsAccess(L0FitsAccess):
54
54
  self.grating_constant_inverse_mm: float = self.header[
55
55
  VispMetadataKey.grating_constant_inverse_mm
56
56
  ]
57
+ # Only present for intensity-mode data
58
+ self.slit_velocity_mm_per_s: float = self.header.get(
59
+ VispMetadataKey.slit_velocity_mm_per_s, HEADER_KEY_NOT_FOUND
60
+ )
57
61
  self.axis_1_type: str = self.header[VispMetadataKey.axis_1_type]
58
62
  self.axis_2_type: str = self.header[VispMetadataKey.axis_2_type]
59
63
  self.axis_3_type: str = self.header[VispMetadataKey.axis_3_type]
@@ -44,9 +44,16 @@ class AssembleVispMovie(AssembleMovie):
44
44
  def num_images(self) -> int:
45
45
  """Total number of images in final movie.
46
46
 
47
- Overloaded from `dkist-processing-common` because DSPS repeat does not correspond to map scan in ViSP
47
+ Overridden from `dkist-processing-common` because DSPS repeat does not correspond to map scan in ViSP.
48
+
49
+ This counts the movie frames actually written by `MakeVispMovieFrames`, rather than trusting
50
+ `self.constants.num_map_scans`. For the map-scan movie-frame path those two numbers are
51
+ always the same (one movie frame per map scan), but for the sit'n'stare movie-frame path a
52
+ single map scan can be chunked into many movie frames, so `num_map_scans` (which correctly
53
+ continues to describe the real map-scan structure of the science data, and is used as such
54
+ elsewhere) doesn't equal the number of movie frames in that case.
48
55
  """
49
- return self.constants.num_map_scans
56
+ return self.count(tags=[VispTag.movie_frame()])
50
57
 
51
58
  def tags_for_image_n(self, n: int) -> list[str]:
52
59
  """Return tags that grab the n'th movie image.