dkist-processing-visp 4.0.0rc1__tar.gz → 5.0.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.
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/CHANGELOG.rst +16 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/PKG-INFO +14 -13
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/SCIENCE_CHANGELOG.rst +10 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.doc.2.rst +2 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.doc.rst +2 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.feature.2.rst +1 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.feature.3.rst +1 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.feature.4.rst +1 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.feature.rst +4 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.misc.2.rst +1 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.misc.3.rst +1 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.misc.rst +2 -0
- dkist_processing_visp-5.0.0rc1/changelog/246.science.rst +11 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/models/constants.py +50 -9
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/models/fits_access.py +5 -1
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/models/metric_code.py +10 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/models/parameters.py +92 -19
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/parsers/spectrograph_configuration.py +75 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/visp_l0_fits_access.py +6 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/geometric.py +115 -7
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/tasks/l1_output_data.py +214 -0
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/tasks/lamp.py +126 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/parse.py +19 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/science.py +14 -14
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/tasks/solar.py +1134 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/visp_base.py +1 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/conftest.py +95 -35
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/header_models.py +71 -20
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/local_trial_workflows/local_trial_helpers.py +25 -1
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/tests/test_assemble_quality.py +118 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_geometric.py +40 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_instrument_polarization.py +2 -1
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_lamp.py +17 -22
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_parameters.py +72 -19
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_parse.py +73 -1
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_science.py +5 -6
- dkist_processing_visp-5.0.0rc1/dkist_processing_visp/tests/test_solar.py +479 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_visp_constants.py +35 -6
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp.egg-info/PKG-INFO +14 -13
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp.egg-info/SOURCES.txt +12 -6
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp.egg-info/requires.txt +13 -12
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/conf.py +4 -1
- dkist_processing_visp-5.0.0rc1/docs/gain_correction.rst +118 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/pyproject.toml +15 -14
- dkist_processing_visp-4.0.0rc1/changelog/235.bugfix.rst +0 -1
- dkist_processing_visp-4.0.0rc1/changelog/235.misc.rst +0 -1
- dkist_processing_visp-4.0.0rc1/changelog/235.science.rst +0 -1
- dkist_processing_visp-4.0.0rc1/changelog/242.bugfix.rst +0 -1
- dkist_processing_visp-4.0.0rc1/changelog/242.science.rst +0 -1
- dkist_processing_visp-4.0.0rc1/dkist_processing_visp/tasks/l1_output_data.py +0 -14
- dkist_processing_visp-4.0.0rc1/dkist_processing_visp/tasks/lamp.py +0 -167
- dkist_processing_visp-4.0.0rc1/dkist_processing_visp/tasks/mixin/line_zones.py +0 -116
- dkist_processing_visp-4.0.0rc1/dkist_processing_visp/tasks/solar.py +0 -742
- dkist_processing_visp-4.0.0rc1/dkist_processing_visp/tests/test_assemble_quality.py +0 -41
- dkist_processing_visp-4.0.0rc1/dkist_processing_visp/tests/test_solar.py +0 -268
- dkist_processing_visp-4.0.0rc1/docs/gain_correction.rst +0 -110
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/.gitignore +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/.pre-commit-config.yaml +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/.readthedocs.yml +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/.snyk +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/README.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/bitbucket-pipelines.yml +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/changelog/.gitempty +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/config.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/fonts/Lato-Regular.ttf +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/models/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/models/tags.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/models/task_name.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/map_repeats.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/modulator_states.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/polarimeter_mode.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/raster_step.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/time.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/parsers/visp_l1_fits_access.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/assemble_movie.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/background_light.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/dark.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/instrument_polarization.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/make_movie_frames.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/mixin/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/mixin/beam_access.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/mixin/corrections.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/mixin/downsample.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/quality_metrics.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tasks/write_l1.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/README.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/local_trial_workflows/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_cals_only.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_polcals_as_science.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_solar_gain_as_science.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/local_trial_workflows/l0_to_l1.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_assemble_movie.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_background_light.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_dark.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_downsample.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_fits_access.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_make_movie_frames.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_map_repeats.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_quality.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_trial_create_quality_report.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_workflows.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/tests/test_write_l1.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/workflows/__init__.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/workflows/l0_processing.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/workflows/single_task_workflows.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp/workflows/trial_workflows.py +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp.egg-info/dependency_links.txt +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/dkist_processing_visp.egg-info/top_level.txt +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/Makefile +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/background_light.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/changelog.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/geometric.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/index.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/l0_to_l1_visp.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/l0_to_l1_visp_full-trial.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/landing_page.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/make.bat +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/polarization_calibration.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/requirements.txt +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/requirements_table.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/science_calibration.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/docs/scientific_changelog.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/licenses/LICENSE.rst +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/science_towncrier.sh +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/setup.cfg +0 -0
- {dkist_processing_visp-4.0.0rc1 → dkist_processing_visp-5.0.0rc1}/towncrier_science.toml +0 -0
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
v4.0.0 (2025-11-12)
|
|
2
|
+
===================
|
|
3
|
+
|
|
4
|
+
Bugfixes
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
- Change how interpolations are done by copying edge pixels as opposed to reflecting them when filling gaps left behind by shifts. This will eliminate "ghost" lines. (`#235 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/235>`__)
|
|
8
|
+
- Update how edges are cropped in areas where both beams did not contribute to the L1 data array. The wrong edges were being cropped before. (`#242 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/242>`__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Misc
|
|
12
|
+
----
|
|
13
|
+
|
|
14
|
+
- Replace L1 frame pixels with NaNs where the source data comes from a single beam. (`#235 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/235>`__)
|
|
15
|
+
|
|
16
|
+
|
|
1
17
|
v3.6.3 (2025-11-04)
|
|
2
18
|
===================
|
|
3
19
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dkist-processing-visp
|
|
3
|
-
Version:
|
|
3
|
+
Version: 5.0.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,13 +13,14 @@ 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.8.
|
|
16
|
+
Requires-Dist: dkist-processing-common==11.8.1rc2
|
|
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
|
|
20
20
|
Requires-Dist: dkist-fits-specifications==4.17.0
|
|
21
21
|
Requires-Dist: dkist-service-configuration==4.1.7
|
|
22
22
|
Requires-Dist: dkist-spectral-lines==3.0.0
|
|
23
|
+
Requires-Dist: solar-wavelength-calibration==2.0.0rc3
|
|
23
24
|
Requires-Dist: astropy==7.0.2
|
|
24
25
|
Requires-Dist: numpy==2.2.5
|
|
25
26
|
Requires-Dist: sunpy==6.1.1
|
|
@@ -116,19 +117,19 @@ Requires-Dist: asdf==3.5.0; extra == "frozen"
|
|
|
116
117
|
Requires-Dist: asdf_standard==1.4.0; extra == "frozen"
|
|
117
118
|
Requires-Dist: asdf_transform_schemas==0.6.0; extra == "frozen"
|
|
118
119
|
Requires-Dist: asgiref==3.10.0; extra == "frozen"
|
|
119
|
-
Requires-Dist: asteval==1.0.
|
|
120
|
+
Requires-Dist: asteval==1.0.7; extra == "frozen"
|
|
120
121
|
Requires-Dist: astropy==7.0.2; extra == "frozen"
|
|
121
|
-
Requires-Dist: astropy-iers-data==0.2025.11.
|
|
122
|
+
Requires-Dist: astropy-iers-data==0.2025.11.10.0.38.31; extra == "frozen"
|
|
122
123
|
Requires-Dist: asyncpg==0.30.0; extra == "frozen"
|
|
123
124
|
Requires-Dist: attrs==25.4.0; extra == "frozen"
|
|
124
125
|
Requires-Dist: babel==2.17.0; extra == "frozen"
|
|
125
126
|
Requires-Dist: billiard==4.2.2; extra == "frozen"
|
|
126
127
|
Requires-Dist: blinker==1.9.0; extra == "frozen"
|
|
127
|
-
Requires-Dist: boto3==1.40.
|
|
128
|
-
Requires-Dist: botocore==1.40.
|
|
128
|
+
Requires-Dist: boto3==1.40.71; extra == "frozen"
|
|
129
|
+
Requires-Dist: botocore==1.40.71; extra == "frozen"
|
|
129
130
|
Requires-Dist: cachelib==0.13.0; extra == "frozen"
|
|
130
131
|
Requires-Dist: celery==5.3.1; extra == "frozen"
|
|
131
|
-
Requires-Dist: certifi==2025.
|
|
132
|
+
Requires-Dist: certifi==2025.11.12; extra == "frozen"
|
|
132
133
|
Requires-Dist: cffi==2.0.0; extra == "frozen"
|
|
133
134
|
Requires-Dist: charset-normalizer==3.4.4; extra == "frozen"
|
|
134
135
|
Requires-Dist: click==8.3.0; extra == "frozen"
|
|
@@ -148,11 +149,11 @@ Requires-Dist: dacite==1.9.2; extra == "frozen"
|
|
|
148
149
|
Requires-Dist: decorator==5.2.1; extra == "frozen"
|
|
149
150
|
Requires-Dist: dill==0.4.0; extra == "frozen"
|
|
150
151
|
Requires-Dist: dkist-header-validator==5.2.1; extra == "frozen"
|
|
151
|
-
Requires-Dist: dkist-processing-common==11.8.
|
|
152
|
+
Requires-Dist: dkist-processing-common==11.8.1rc2; extra == "frozen"
|
|
152
153
|
Requires-Dist: dkist-processing-core==6.0.0; extra == "frozen"
|
|
153
154
|
Requires-Dist: dkist-processing-math==2.2.1; extra == "frozen"
|
|
154
155
|
Requires-Dist: dkist-processing-pac==3.1.1; extra == "frozen"
|
|
155
|
-
Requires-Dist: dkist-processing-visp==
|
|
156
|
+
Requires-Dist: dkist-processing-visp==5.0.0rc1; extra == "frozen"
|
|
156
157
|
Requires-Dist: dkist-service-configuration==4.1.7; extra == "frozen"
|
|
157
158
|
Requires-Dist: dkist-spectral-lines==3.0.0; extra == "frozen"
|
|
158
159
|
Requires-Dist: dkist_fits_specifications==4.17.0; extra == "frozen"
|
|
@@ -165,7 +166,7 @@ Requires-Dist: frozenlist==1.8.0; extra == "frozen"
|
|
|
165
166
|
Requires-Dist: fsspec==2025.10.0; extra == "frozen"
|
|
166
167
|
Requires-Dist: globus-sdk==3.65.0; extra == "frozen"
|
|
167
168
|
Requires-Dist: google-re2==1.1.20251105; extra == "frozen"
|
|
168
|
-
Requires-Dist: googleapis-common-protos==1.
|
|
169
|
+
Requires-Dist: googleapis-common-protos==1.72.0; extra == "frozen"
|
|
169
170
|
Requires-Dist: gqlclient==1.2.3; extra == "frozen"
|
|
170
171
|
Requires-Dist: greenlet==3.2.4; extra == "frozen"
|
|
171
172
|
Requires-Dist: grpcio==1.76.0; extra == "frozen"
|
|
@@ -255,7 +256,7 @@ Requires-Dist: psutil==7.1.3; extra == "frozen"
|
|
|
255
256
|
Requires-Dist: psycopg2-binary==2.9.11; extra == "frozen"
|
|
256
257
|
Requires-Dist: pycparser==2.23; extra == "frozen"
|
|
257
258
|
Requires-Dist: pydantic==2.12.4; extra == "frozen"
|
|
258
|
-
Requires-Dist: pydantic-settings==2.
|
|
259
|
+
Requires-Dist: pydantic-settings==2.12.0; extra == "frozen"
|
|
259
260
|
Requires-Dist: pydantic_core==2.41.5; extra == "frozen"
|
|
260
261
|
Requires-Dist: pyerfa==2.0.1.5; extra == "frozen"
|
|
261
262
|
Requires-Dist: pyparsing==3.2.5; extra == "frozen"
|
|
@@ -281,7 +282,7 @@ Requires-Dist: semantic-version==2.10.0; extra == "frozen"
|
|
|
281
282
|
Requires-Dist: setproctitle==1.3.7; extra == "frozen"
|
|
282
283
|
Requires-Dist: six==1.17.0; extra == "frozen"
|
|
283
284
|
Requires-Dist: sniffio==1.3.1; extra == "frozen"
|
|
284
|
-
Requires-Dist: solar-wavelength-calibration==
|
|
285
|
+
Requires-Dist: solar-wavelength-calibration==2.0.0rc3; extra == "frozen"
|
|
285
286
|
Requires-Dist: sqids==0.5.1; extra == "frozen"
|
|
286
287
|
Requires-Dist: sqlparse==0.5.3; extra == "frozen"
|
|
287
288
|
Requires-Dist: sunpy==6.1.1; extra == "frozen"
|
|
@@ -300,7 +301,7 @@ Requires-Dist: typing_extensions==4.15.0; extra == "frozen"
|
|
|
300
301
|
Requires-Dist: tzdata==2025.2; extra == "frozen"
|
|
301
302
|
Requires-Dist: uc-micro-py==1.0.3; extra == "frozen"
|
|
302
303
|
Requires-Dist: uncertainties==3.2.3; extra == "frozen"
|
|
303
|
-
Requires-Dist: universal_pathlib==0.3.
|
|
304
|
+
Requires-Dist: universal_pathlib==0.3.5; extra == "frozen"
|
|
304
305
|
Requires-Dist: urllib3==2.5.0; extra == "frozen"
|
|
305
306
|
Requires-Dist: vine==5.1.0; extra == "frozen"
|
|
306
307
|
Requires-Dist: voluptuous==0.15.2; extra == "frozen"
|
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
v4.0.0 (2025-11-12)
|
|
2
|
+
===================
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
- Change how interpolations are done by copying edge pixels as opposed to reflecting them when filling gaps left behind by shifts. This will eliminate "ghost" lines. Replace L1 frame pixels with NaNs where the source data comes from a single beam. (`#235 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/235>`__)
|
|
8
|
+
- Update how edges are cropped in areas where both beams did not contribute to the L1 data array. The wrong edges were being cropped before. (`#242 <https://bitbucket.org/dkistdc/dkist-processing-visp/pull-requests/242>`__)
|
|
9
|
+
|
|
10
|
+
|
|
1
11
|
v3.0.0 (2025-04-01)
|
|
2
12
|
===================
|
|
3
13
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Only compute a single lamp gain for each beam. In the past a single map gain was also computed for each modulation state.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add Buds to parse the spectrograph setup into pipeline constants to be used when fitting a solar atlas.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Add quality report metrics that show the quality of the vignette estimation in the Solar Gain tasks.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Update the Solar Gain task to measure vignetting signal, compute a single gain for each beam (as opposed to for each beam and modulator state),
|
|
2
|
+
and stop applying residual spectral shifts to the characteristic spectra before removing from the input gain array.
|
|
3
|
+
See the `Science Changelog <https://docs.dkist.nso.edu/projects/visp/en/stable/scientific_changelog.html>`_ and
|
|
4
|
+
`gain algorithm docs <https://docs.dkist.nso.edu/projects/visp/en/stable/gain_correction.html>`_ for more information.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Remove the `LineZonesMixin` and move its methods directly to the Geometric calibration task, which is now the only task that uses them.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Rename the ``solar_spectral_avg_window`` to ``solar_spatial_median_filter_width_px`` to more accurately capture what it does.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Major update to the gain algorithm to mitigate polarization artifacts in L1 science frames. This change can be split into
|
|
2
|
+
three parts. See the `gain correction <https://docs.dkist.nso.edu/projects/visp/en/stable/gain_correction.html>`_ page for more information.
|
|
3
|
+
|
|
4
|
+
#. Compute a single gain correction image for each beam. In the past we had computed a separate gain image for each modstate as well, but this was found to couple residual polarization structure into the final science frames.
|
|
5
|
+
|
|
6
|
+
#. Stop "refining" (i.e., applying small spectral offsets to) the characteristic solar spectrum on a per-spatial-pixel basis. This was initially done to minimize line residuals in Telluric lines but was found to have a more-negative on polarimetric residuals.
|
|
7
|
+
|
|
8
|
+
#. Separate vignetting caused by aperture masks from the solar signal used to remove spectral lines in the final gain image. This is done by fitting a solar atlas and taking the deviation in continuum to be the vignetting signal.
|
|
9
|
+
|
|
10
|
+
Computing a single gain per beam will greatly reduce the polarization artifacts in L1 data. Measuring the vignette
|
|
11
|
+
signal directly will further reduce these artifacts and improve flatness across the array.
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
from enum import Enum
|
|
4
4
|
|
|
5
|
+
import astropy.units as u
|
|
6
|
+
from astropy.units import Quantity
|
|
5
7
|
from dkist_processing_common.models.constants import ConstantsBase
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class VispBudName(Enum):
|
|
9
11
|
"""Names to be used in Visp buds."""
|
|
10
12
|
|
|
13
|
+
arm_id = "ARM_ID"
|
|
11
14
|
num_raster_steps = "NUM_RASTER_STEPS"
|
|
12
15
|
polarimeter_mode = "POLARIMETER_MODE"
|
|
13
16
|
wavelength = "WAVELENGTH"
|
|
@@ -22,6 +25,10 @@ class VispBudName(Enum):
|
|
|
22
25
|
polcal_readout_exp_times = "POLCAL_READOUT_EXP_TIMES"
|
|
23
26
|
non_dark_task_readout_exp_times = "NON_DARK_TASK_READOUT_EXP_TIMES"
|
|
24
27
|
num_map_scans = "NUM_MAP_SCANS"
|
|
28
|
+
incident_light_angle_deg = "INCIDENT_LIGHT_ANGLE_DEG"
|
|
29
|
+
reflected_light_angle_deg = "REFLECTED_LIGHT_ANGLE_DEG"
|
|
30
|
+
grating_constant_inverse_mm = "GRATING_CONSTANT_INVERSE_MM"
|
|
31
|
+
solar_gain_ip_start_time = "SOLAR_GAIN_IP_START_TIME"
|
|
25
32
|
axis_1_type = "AXIS_1_TYPE"
|
|
26
33
|
axis_2_type = "AXIS_2_TYPE"
|
|
27
34
|
axis_3_type = "AXIS_3_TYPE"
|
|
@@ -31,6 +38,16 @@ class VispBudName(Enum):
|
|
|
31
38
|
class VispConstants(ConstantsBase):
|
|
32
39
|
"""Visp specific constants to add to the common constants."""
|
|
33
40
|
|
|
41
|
+
@property
|
|
42
|
+
def arm_id(self) -> str:
|
|
43
|
+
"""
|
|
44
|
+
Return the current ViSP arm ID.
|
|
45
|
+
|
|
46
|
+
Arm IDs are ints in the headers, but we convert them to str here because that's what downstream machinery expects
|
|
47
|
+
the type to be.
|
|
48
|
+
"""
|
|
49
|
+
return str(self._db_dict[VispBudName.arm_id])
|
|
50
|
+
|
|
34
51
|
@property
|
|
35
52
|
def wavelength(self) -> float:
|
|
36
53
|
"""Wavelength."""
|
|
@@ -76,17 +93,17 @@ class VispConstants(ConstantsBase):
|
|
|
76
93
|
raise ValueError(f"No init set known for {retarder_name = }")
|
|
77
94
|
|
|
78
95
|
@property
|
|
79
|
-
def lamp_exposure_times(self) -> [float]:
|
|
96
|
+
def lamp_exposure_times(self) -> list[float]:
|
|
80
97
|
"""Find the lamp exposure time."""
|
|
81
98
|
return self._db_dict[VispBudName.lamp_exposure_times.value]
|
|
82
99
|
|
|
83
100
|
@property
|
|
84
|
-
def solar_exposure_times(self) -> [float]:
|
|
101
|
+
def solar_exposure_times(self) -> list[float]:
|
|
85
102
|
"""Find the solar exposure time."""
|
|
86
103
|
return self._db_dict[VispBudName.solar_exposure_times.value]
|
|
87
104
|
|
|
88
105
|
@property
|
|
89
|
-
def polcal_exposure_times(self) -> [float]:
|
|
106
|
+
def polcal_exposure_times(self) -> list[float]:
|
|
90
107
|
"""Find the polarization calibration exposure time."""
|
|
91
108
|
if self.correct_for_polarization:
|
|
92
109
|
return self._db_dict[VispBudName.polcal_exposure_times.value]
|
|
@@ -94,22 +111,22 @@ class VispConstants(ConstantsBase):
|
|
|
94
111
|
return []
|
|
95
112
|
|
|
96
113
|
@property
|
|
97
|
-
def observe_exposure_times(self) -> [float]:
|
|
114
|
+
def observe_exposure_times(self) -> list[float]:
|
|
98
115
|
"""Find the observation exposure time."""
|
|
99
116
|
return self._db_dict[VispBudName.observe_exposure_times.value]
|
|
100
117
|
|
|
101
118
|
@property
|
|
102
|
-
def lamp_readout_exp_times(self) -> [float]:
|
|
119
|
+
def lamp_readout_exp_times(self) -> list[float]:
|
|
103
120
|
"""Find the lamp readout exposure time."""
|
|
104
121
|
return self._db_dict[VispBudName.lamp_readout_exp_times.value]
|
|
105
122
|
|
|
106
123
|
@property
|
|
107
|
-
def solar_readout_exp_times(self) -> [float]:
|
|
124
|
+
def solar_readout_exp_times(self) -> list[float]:
|
|
108
125
|
"""Find the solar readout exposure time."""
|
|
109
126
|
return self._db_dict[VispBudName.solar_readout_exp_times.value]
|
|
110
127
|
|
|
111
128
|
@property
|
|
112
|
-
def polcal_readout_exp_times(self) -> [float]:
|
|
129
|
+
def polcal_readout_exp_times(self) -> list[float]:
|
|
113
130
|
"""Find the polarization calibration readout exposure time."""
|
|
114
131
|
if self.correct_for_polarization:
|
|
115
132
|
return self._db_dict[VispBudName.polcal_readout_exp_times.value]
|
|
@@ -117,7 +134,7 @@ class VispConstants(ConstantsBase):
|
|
|
117
134
|
return []
|
|
118
135
|
|
|
119
136
|
@property
|
|
120
|
-
def non_dark_task_readout_exp_times(self) -> [float]:
|
|
137
|
+
def non_dark_task_readout_exp_times(self) -> list[float]:
|
|
121
138
|
"""
|
|
122
139
|
Find all readout exposure times that *need* to exist in a dark IP.
|
|
123
140
|
|
|
@@ -127,10 +144,34 @@ class VispConstants(ConstantsBase):
|
|
|
127
144
|
return self._db_dict[VispBudName.non_dark_task_readout_exp_times.value]
|
|
128
145
|
|
|
129
146
|
@property
|
|
130
|
-
def observe_readout_exp_times(self) -> [float]:
|
|
147
|
+
def observe_readout_exp_times(self) -> list[float]:
|
|
131
148
|
"""Find the observation readout exposure time."""
|
|
132
149
|
return self._db_dict[VispBudName.observe_readout_exp_times.value]
|
|
133
150
|
|
|
151
|
+
@property
|
|
152
|
+
def incident_light_angle_deg(self) -> Quantity:
|
|
153
|
+
"""Return the spectrograph incident light angle [deg]."""
|
|
154
|
+
return self._db_dict[VispBudName.incident_light_angle_deg] * u.deg
|
|
155
|
+
|
|
156
|
+
@property
|
|
157
|
+
def reflected_light_angle_deg(self) -> Quantity:
|
|
158
|
+
"""
|
|
159
|
+
Return the spectrograph reflected light angle [deg].
|
|
160
|
+
|
|
161
|
+
This angle is the incident light angle plus the angular position of the ViSP arm.
|
|
162
|
+
"""
|
|
163
|
+
return self._db_dict[VispBudName.reflected_light_angle_deg] * u.deg
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def grating_constant_inverse_mm(self) -> Quantity:
|
|
167
|
+
"""Return the spectrograph grating constant [1/mm]."""
|
|
168
|
+
return self._db_dict[VispBudName.grating_constant_inverse_mm] / u.mm
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def solar_gain_ip_start_time(self) -> str:
|
|
172
|
+
"""Return the start time of the SOLAR GAIN Instrument Program."""
|
|
173
|
+
return self._db_dict[VispBudName.solar_gain_ip_start_time]
|
|
174
|
+
|
|
134
175
|
@property
|
|
135
176
|
def axis_1_type(self) -> str:
|
|
136
177
|
"""Find the type of the first array axis."""
|
|
@@ -6,11 +6,15 @@ from enum import StrEnum
|
|
|
6
6
|
class VispMetadataKey(StrEnum):
|
|
7
7
|
"""Controlled list of names for FITS metadata header keys."""
|
|
8
8
|
|
|
9
|
+
arm_id = "VSPARMID"
|
|
10
|
+
number_of_modulator_states = "VSPNUMST"
|
|
9
11
|
raster_scan_step = "VSPSTP"
|
|
10
12
|
total_raster_steps = "VSPNSTP"
|
|
11
13
|
modulator_state = "VSPSTNUM"
|
|
12
|
-
number_of_modulator_states = "VSPNUMST"
|
|
13
14
|
polarimeter_mode = "VISP_006"
|
|
15
|
+
grating_angle_deg = "VSPGRTAN"
|
|
16
|
+
arm_position_deg = "VSPARMPS"
|
|
17
|
+
grating_constant_inverse_mm = "VSPGRTCN"
|
|
14
18
|
axis_1_type = "CTYPE1"
|
|
15
19
|
axis_2_type = "CTYPE2"
|
|
16
20
|
axis_3_type = "CTYPE3"
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"""Controlled list of quality metric codes."""
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class VispMetricCode(StrEnum):
|
|
7
|
+
"""Controlled list of quality metric codes."""
|
|
8
|
+
|
|
9
|
+
solar_first_vignette = "SOLAR_CAL_FIRST_VIGNETTE"
|
|
10
|
+
solar_final_vignette = "SOLAR_CAL_FINAL_VIGNETTE"
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
"""Visp calibration pipeline parameters."""
|
|
2
2
|
|
|
3
3
|
from datetime import datetime
|
|
4
|
+
from typing import Any
|
|
4
5
|
|
|
6
|
+
import astropy.units as u
|
|
7
|
+
from dkist_processing_common.models.parameters import ParameterArmIdMixin
|
|
5
8
|
from dkist_processing_common.models.parameters import ParameterBase
|
|
6
9
|
from dkist_processing_common.models.parameters import ParameterWavelengthMixin
|
|
10
|
+
from solar_wavelength_calibration import DownloadConfig
|
|
7
11
|
|
|
8
12
|
|
|
9
13
|
class VispParsingParameters(ParameterBase):
|
|
@@ -22,7 +26,7 @@ class VispParsingParameters(ParameterBase):
|
|
|
22
26
|
)
|
|
23
27
|
|
|
24
28
|
|
|
25
|
-
class VispParameters(ParameterBase, ParameterWavelengthMixin):
|
|
29
|
+
class VispParameters(ParameterBase, ParameterWavelengthMixin, ParameterArmIdMixin):
|
|
26
30
|
"""Put all Visp parameters parsed from the input dataset document in a single property."""
|
|
27
31
|
|
|
28
32
|
@property
|
|
@@ -69,7 +73,7 @@ class VispParameters(ParameterBase, ParameterWavelengthMixin):
|
|
|
69
73
|
|
|
70
74
|
@property
|
|
71
75
|
def hairline_mask_spatial_smoothing_width_px(self) -> float:
|
|
72
|
-
"""Amount to smooth the
|
|
76
|
+
"""Amount to smooth the hairline mask in the spatial direction.
|
|
73
77
|
|
|
74
78
|
This helps capture the higher-flux wings of the hairlines that would otherwise require a `hairline_fraction`
|
|
75
79
|
that was so low it captures other optical features.
|
|
@@ -134,9 +138,34 @@ class VispParameters(ParameterBase, ParameterWavelengthMixin):
|
|
|
134
138
|
return self._find_most_recent_past_value("visp_geo_poly_fit_order")
|
|
135
139
|
|
|
136
140
|
@property
|
|
137
|
-
def
|
|
141
|
+
def geo_zone_prominence(self):
|
|
142
|
+
"""Relative peak prominence threshold used to identify strong spectral features."""
|
|
143
|
+
return self._find_parameter_closest_wavelength("visp_geo_zone_prominence")
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def geo_zone_width(self):
|
|
147
|
+
"""Pixel width used to search for strong spectral features."""
|
|
148
|
+
return self._find_parameter_closest_wavelength("visp_geo_zone_width")
|
|
149
|
+
|
|
150
|
+
@property
|
|
151
|
+
def geo_zone_bg_order(self):
|
|
152
|
+
"""Order of polynomial fit used to remove continuum when identifying strong spectral features."""
|
|
153
|
+
return self._find_parameter_closest_wavelength("visp_geo_zone_bg_order")
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def geo_zone_normalization_percentile(self):
|
|
157
|
+
"""Fraction of CDF to use for normalizing spectrum when search for strong features."""
|
|
158
|
+
return self._find_parameter_closest_wavelength("visp_geo_zone_normalization_percentile")
|
|
159
|
+
|
|
160
|
+
@property
|
|
161
|
+
def geo_zone_rel_height(self):
|
|
162
|
+
"""Relative height at which to compute the width of strong spectral features."""
|
|
163
|
+
return self._find_most_recent_past_value("visp_geo_zone_rel_height")
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def solar_spatial_median_filter_width_px(self):
|
|
138
167
|
"""Pixel width of spatial median filter used to compute characteristic solar spectra."""
|
|
139
|
-
return self._find_parameter_closest_wavelength("
|
|
168
|
+
return self._find_parameter_closest_wavelength("visp_solar_spatial_median_filter_width_px")
|
|
140
169
|
|
|
141
170
|
@property
|
|
142
171
|
def solar_characteristic_spatial_normalization_percentile(self) -> float:
|
|
@@ -146,29 +175,73 @@ class VispParameters(ParameterBase, ParameterWavelengthMixin):
|
|
|
146
175
|
)
|
|
147
176
|
|
|
148
177
|
@property
|
|
149
|
-
def
|
|
150
|
-
"""
|
|
151
|
-
|
|
178
|
+
def solar_vignette_initial_continuum_poly_fit_order(self) -> int:
|
|
179
|
+
"""
|
|
180
|
+
Define the order of polynomial to use when fitting the initial continuum function.
|
|
181
|
+
|
|
182
|
+
Note that "initial" in this context does not refer to an initial guess in the wavecal fitter, but rather the
|
|
183
|
+
fact that this represents the initial estimate of the vignette signal.
|
|
184
|
+
"""
|
|
185
|
+
return self._find_most_recent_past_value(
|
|
186
|
+
"visp_solar_vignette_initial_continuum_poly_fit_order"
|
|
187
|
+
)
|
|
152
188
|
|
|
153
189
|
@property
|
|
154
|
-
def
|
|
155
|
-
"""
|
|
156
|
-
return self.
|
|
190
|
+
def solar_vignette_wavecal_fit_kwargs(self) -> dict[str, Any]:
|
|
191
|
+
"""Define extra keyword arguments to pass to the wavelength calibration fitter."""
|
|
192
|
+
return self._find_most_recent_past_value("visp_solar_vignette_wavecal_fit_kwargs")
|
|
157
193
|
|
|
158
194
|
@property
|
|
159
|
-
def
|
|
160
|
-
"""
|
|
161
|
-
return self.
|
|
195
|
+
def solar_vignette_spectral_poly_fit_order(self) -> int:
|
|
196
|
+
"""Define the order of spectral polynomial used when computing the full, 2D vignette signal."""
|
|
197
|
+
return self._find_most_recent_past_value("visp_solar_vignette_spectral_poly_fit_order")
|
|
162
198
|
|
|
163
199
|
@property
|
|
164
|
-
def
|
|
165
|
-
"""
|
|
166
|
-
return self.
|
|
200
|
+
def solar_vignette_min_samples(self) -> float:
|
|
201
|
+
"""Return fractional number of samples required for the RANSAC regressor used to fit the 2D vignette signal."""
|
|
202
|
+
return self._find_most_recent_past_value("visp_solar_vignette_min_samples")
|
|
167
203
|
|
|
168
204
|
@property
|
|
169
|
-
def
|
|
170
|
-
"""
|
|
171
|
-
|
|
205
|
+
def wavecal_camera_lens_parameters(self) -> list[u.Quantity]:
|
|
206
|
+
r"""
|
|
207
|
+
Define the 2nd order polynomial coefficients for computing the total camera focal length as a function of wavelength.
|
|
208
|
+
|
|
209
|
+
The total focal length of the lens is :math:`f = a_0 + a_1\lambda + a_2\lambda^2` where this property is
|
|
210
|
+
:math:`[a_0, a_1, a_2]`
|
|
211
|
+
"""
|
|
212
|
+
value_list = self._find_parameter_for_arm("visp_wavecal_camera_lens_parameters")
|
|
213
|
+
unit_list = [u.m, u.m / u.nm, u.m / u.nm**2]
|
|
214
|
+
return [v * u for v, u in zip(value_list, unit_list)]
|
|
215
|
+
|
|
216
|
+
@property
|
|
217
|
+
def wavecal_pixel_pitch_micron_per_pix(self) -> u.Quantity:
|
|
218
|
+
"""Define the physical size of ViSP detector pixels."""
|
|
219
|
+
return (
|
|
220
|
+
self._find_most_recent_past_value("visp_wavecal_pixel_pitch_micron_per_pix")
|
|
221
|
+
* u.micron
|
|
222
|
+
/ u.pix
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
@property
|
|
226
|
+
def wavecal_atlas_download_config(self) -> DownloadConfig:
|
|
227
|
+
"""Define the `~solar_wavelength_calibration.DownloadConfig` used to grab the Solar atlas used for wavelength calibration."""
|
|
228
|
+
config_dict = self._find_most_recent_past_value("visp_wavecal_atlas_download_config")
|
|
229
|
+
return DownloadConfig.model_validate(config_dict)
|
|
230
|
+
|
|
231
|
+
@property
|
|
232
|
+
def wavecal_init_resolving_power(self) -> int:
|
|
233
|
+
"""Define the initial guess for ViSP resolving power in wavecal fits."""
|
|
234
|
+
return self._find_most_recent_past_value("visp_wavecal_init_resolving_power")
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def wavecal_init_straylight_fraction(self) -> float:
|
|
238
|
+
"""Define the initial guess for straylight fraction in wavecal fits."""
|
|
239
|
+
return self._find_most_recent_past_value("visp_wavecal_init_straylight_fraction")
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def wavecal_init_opacity_factor(self) -> float:
|
|
243
|
+
"""Define the initial guess for opacity factor in wavecal fits."""
|
|
244
|
+
return self._find_most_recent_past_value("visp_wavecal_init_opacity_factor")
|
|
172
245
|
|
|
173
246
|
@property
|
|
174
247
|
def polcal_spatial_median_filter_width_px(self) -> int:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Buds for parsing the incident and reflected light angles of the ViSP spectrograph."""
|
|
2
|
+
|
|
3
|
+
from dkist_processing_common.models.flower_pot import SpilledDirt
|
|
4
|
+
from dkist_processing_common.models.flower_pot import Stem
|
|
5
|
+
from dkist_processing_common.models.task_name import TaskName
|
|
6
|
+
from dkist_processing_common.parsers.task import parse_header_ip_task_with_gains
|
|
7
|
+
from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
|
|
8
|
+
|
|
9
|
+
from dkist_processing_visp.models.constants import VispBudName
|
|
10
|
+
from dkist_processing_visp.models.fits_access import VispMetadataKey
|
|
11
|
+
from dkist_processing_visp.parsers.visp_l0_fits_access import VispL0FitsAccess
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def convert_grating_angle_to_incident_light_angle(grating_angle: float) -> float:
|
|
15
|
+
"""Convert the raw header "grating angle" to the incident light angle expected by the solar wavecal library."""
|
|
16
|
+
return -1 * grating_angle
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class IncidentLightAngleBud(TaskUniqueBud):
|
|
20
|
+
"""Special case of `TaskUniqueBud` so we can apply the sign shift to the header incident light angle values."""
|
|
21
|
+
|
|
22
|
+
def __init__(self):
|
|
23
|
+
super().__init__(
|
|
24
|
+
constant_name=VispBudName.incident_light_angle_deg.value,
|
|
25
|
+
metadata_key=VispMetadataKey.grating_angle_deg,
|
|
26
|
+
ip_task_types=[TaskName.observe.value, TaskName.solar_gain.value],
|
|
27
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def setter(self, fits_obj: VispL0FitsAccess) -> float | type[SpilledDirt]:
|
|
31
|
+
"""Apply a sign flip to the raw header value for incident light angle."""
|
|
32
|
+
grating_angle = super().setter(fits_obj)
|
|
33
|
+
|
|
34
|
+
if grating_angle is SpilledDirt:
|
|
35
|
+
return grating_angle
|
|
36
|
+
|
|
37
|
+
return convert_grating_angle_to_incident_light_angle(grating_angle)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ReflectedLightAngleBud(Stem):
|
|
41
|
+
"""Bud that combines the incident light angle and arm position header values to compute the reflected light angle."""
|
|
42
|
+
|
|
43
|
+
key_to_petal_dict: dict[str, float]
|
|
44
|
+
|
|
45
|
+
def __init__(self):
|
|
46
|
+
super().__init__(stem_name=VispBudName.reflected_light_angle_deg.value)
|
|
47
|
+
self.ip_task_types = [
|
|
48
|
+
task.casefold() for task in [TaskName.observe.value, TaskName.solar_gain.value]
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
def setter(self, fits_obj: VispL0FitsAccess) -> float | type[SpilledDirt]:
|
|
52
|
+
"""
|
|
53
|
+
Compute the reflected light angle.
|
|
54
|
+
|
|
55
|
+
The reflected light angle is `-1 * fits_objs.grating_angle_deg + fits_obj.arm_position_deg`.
|
|
56
|
+
"""
|
|
57
|
+
task = parse_header_ip_task_with_gains(fits_obj)
|
|
58
|
+
|
|
59
|
+
if task.casefold() in self.ip_task_types:
|
|
60
|
+
incident_light_angle = convert_grating_angle_to_incident_light_angle(
|
|
61
|
+
fits_obj.grating_angle_deg
|
|
62
|
+
)
|
|
63
|
+
arm_position = fits_obj.arm_position_deg
|
|
64
|
+
return incident_light_angle + arm_position
|
|
65
|
+
|
|
66
|
+
return SpilledDirt
|
|
67
|
+
|
|
68
|
+
def getter(self, key: str) -> float:
|
|
69
|
+
"""Get the value for the reflected light angle and raise an error if it is not unique."""
|
|
70
|
+
value_set = set(self.key_to_petal_dict.values())
|
|
71
|
+
if len(value_set) > 1:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
f"Multiple {self.stem_name} values found for key {key}. Values: {value_set}"
|
|
74
|
+
)
|
|
75
|
+
return value_set.pop()
|
|
@@ -32,6 +32,7 @@ class VispL0FitsAccess(L0FitsAccess):
|
|
|
32
32
|
):
|
|
33
33
|
super().__init__(hdu=hdu, name=name, auto_squeeze=auto_squeeze)
|
|
34
34
|
|
|
35
|
+
self.arm_id: int = self.header[VispMetadataKey.arm_id]
|
|
35
36
|
self.number_of_modulator_states: int = self.header[
|
|
36
37
|
VispMetadataKey.number_of_modulator_states
|
|
37
38
|
]
|
|
@@ -39,6 +40,11 @@ class VispL0FitsAccess(L0FitsAccess):
|
|
|
39
40
|
self.total_raster_steps: int = self.header[VispMetadataKey.total_raster_steps]
|
|
40
41
|
self.modulator_state: int = self.header[VispMetadataKey.modulator_state]
|
|
41
42
|
self.polarimeter_mode: str = self.header[VispMetadataKey.polarimeter_mode]
|
|
43
|
+
self.grating_angle_deg: float = self.header[VispMetadataKey.grating_angle_deg]
|
|
44
|
+
self.arm_position_deg: float = self.header[VispMetadataKey.arm_position_deg]
|
|
45
|
+
self.grating_constant_inverse_mm: float = self.header[
|
|
46
|
+
VispMetadataKey.grating_constant_inverse_mm
|
|
47
|
+
]
|
|
42
48
|
self.axis_1_type: str = self.header[VispMetadataKey.axis_1_type]
|
|
43
49
|
self.axis_2_type: str = self.header[VispMetadataKey.axis_2_type]
|
|
44
50
|
self.axis_3_type: str = self.header[VispMetadataKey.axis_3_type]
|