dkist-processing-cryonirsp 1.19.19__tar.gz → 2.0.0rc2__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_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/PKG-INFO +40 -36
- dkist_processing_cryonirsp-2.0.0rc2/changelog/289.bugfix.rst +2 -0
- dkist_processing_cryonirsp-2.0.0rc2/changelog/292.feature.2.rst +3 -0
- dkist_processing_cryonirsp-2.0.0rc2/changelog/292.feature.rst +2 -0
- dkist_processing_cryonirsp-2.0.0rc2/changelog/292.misc.rst +3 -0
- dkist_processing_cryonirsp-2.0.0rc2/changelog/292.science.rst +4 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/parameters.py +25 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/instrument_polarization.py +3 -2
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/sp_geometric.py +168 -88
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/conftest.py +6 -1
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/local_trial_workflows/l0_cals_only.py +24 -5
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/local_trial_workflows/l0_to_l1.py +24 -5
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/local_trial_workflows/linearize_only.py +22 -3
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/local_trial_workflows/local_trial_helpers.py +54 -1
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_instrument_polarization.py +99 -8
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp.egg-info/PKG-INFO +40 -36
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp.egg-info/SOURCES.txt +5 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp.egg-info/requires.txt +39 -35
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp.egg-info/scm_file_list.json +110 -105
- dkist_processing_cryonirsp-2.0.0rc2/dkist_processing_cryonirsp.egg-info/scm_version.json +8 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/pyproject.toml +41 -37
- dkist_processing_cryonirsp-1.19.19/dkist_processing_cryonirsp.egg-info/scm_version.json +0 -8
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/.gitignore +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/.pre-commit-config.yaml +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/.readthedocs.yml +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/.rovodev/.review-agent.md +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/.snyk +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/CHANGELOG.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/README.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/SCIENCE_CHANGELOG.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/bitbucket-pipelines.yml +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/changelog/.gitempty +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/codecs/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/codecs/fits.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/config.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/beam_boundaries.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/constants.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/dataset_extras.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/exposure_conditions.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/fits_access.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/tags.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/models/task_name.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/check_for_gains.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/cryonirsp_l0_fits_access.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/cryonirsp_l1_fits_access.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/exposure_conditions.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/map_repeats.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/measurements.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/modstates.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/optical_density_filters.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/polarimetric_check.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/scan_step.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/parsers/time.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/assemble_movie.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/bad_pixel_map.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/beam_boundaries_base.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/ci_beam_boundaries.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/ci_science.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/cryonirsp_base.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/dark.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/gain.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/l1_output_data.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/linearity_correction.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/make_movie_frames.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/mixin/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/mixin/corrections.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/mixin/shift_measurements.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/parse.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/polcal_as_science.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/quality_metrics.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/science_base.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/sp_beam_boundaries.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/sp_science.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/sp_solar_gain.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/sp_wavelength_calibration.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/write_dataset_extras.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tasks/write_l1.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/header_models.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/local_trial_workflows/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_assemble_movie.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_assemble_qualilty.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_bad_pixel_maps.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_ci_beam_boundaries.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_ci_science.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_corrections.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_cryo_base.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_cryo_constants.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_dark.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_fits_access.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_gain.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_linearity_correction.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_make_movie_frames.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_parameters.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_parse.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_polcal_as_science.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_quality.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_sp_beam_boundaries.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_sp_geometric.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_sp_make_movie_frames.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_sp_science.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_sp_solar.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_sp_wavelength_calibration.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_trial_create_quality_report.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_workflows.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_write_dataset_extras.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/tests/test_write_l1.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/workflows/__init__.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/workflows/ci_l0_processing.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/workflows/sp_l0_processing.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp/workflows/trial_workflows.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp.egg-info/dependency_links.txt +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/dkist_processing_cryonirsp.egg-info/top_level.txt +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/Makefile +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/bad_pixel_calibration.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/beam_angle_calculation.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/beam_boundary_computation.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/changelog.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/ci_science_calibration.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/conf.py +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/dataset_extras.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/index.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/l0_to_l1_cryonirsp_ci-full-trial.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/l0_to_l1_cryonirsp_ci.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/l0_to_l1_cryonirsp_sp-full-trial.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/l0_to_l1_cryonirsp_sp.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/landing_page.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/linearization.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/make.bat +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/requirements.txt +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/requirements_table.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/scientific_changelog.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/sp_science_calibration.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/docs/wavelength_calibration.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/licenses/LICENSE.rst +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/science_towncrier.sh +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/setup.cfg +0 -0
- {dkist_processing_cryonirsp-1.19.19 → dkist_processing_cryonirsp-2.0.0rc2}/towncrier_science.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dkist-processing-cryonirsp
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0rc2
|
|
4
4
|
Summary: Science processing code for the Cryo-NIRSP instrument on DKIST
|
|
5
5
|
Author-email: NSO / AURA <dkistdc@nso.edu>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -29,6 +29,7 @@ Requires-Dist: numba==0.61.2
|
|
|
29
29
|
Requires-Dist: numpy==2.2.5
|
|
30
30
|
Requires-Dist: peakutils==1.3.5
|
|
31
31
|
Requires-Dist: scikit-image==0.25.2
|
|
32
|
+
Requires-Dist: scikit-learn==1.9.0
|
|
32
33
|
Requires-Dist: scipy==1.15.3
|
|
33
34
|
Requires-Dist: sunpy==6.1.1
|
|
34
35
|
Provides-Extra: test
|
|
@@ -80,22 +81,21 @@ Requires-Dist: aiohttp==3.14.1; extra == "frozen"
|
|
|
80
81
|
Requires-Dist: aiosignal==1.4.0; extra == "frozen"
|
|
81
82
|
Requires-Dist: aiosmtplib==5.1.2; extra == "frozen"
|
|
82
83
|
Requires-Dist: aiosqlite==0.21.0; extra == "frozen"
|
|
83
|
-
Requires-Dist: alembic==1.18.
|
|
84
|
+
Requires-Dist: alembic==1.18.5; extra == "frozen"
|
|
84
85
|
Requires-Dist: amqp==5.3.1; extra == "frozen"
|
|
85
86
|
Requires-Dist: annotated-doc==0.0.4; extra == "frozen"
|
|
86
87
|
Requires-Dist: annotated-types==0.7.0; extra == "frozen"
|
|
87
|
-
Requires-Dist: anyio==4.14.
|
|
88
|
+
Requires-Dist: anyio==4.14.1; extra == "frozen"
|
|
88
89
|
Requires-Dist: apache-airflow==3.2.1; extra == "frozen"
|
|
89
90
|
Requires-Dist: apache-airflow-core==3.2.1; extra == "frozen"
|
|
90
91
|
Requires-Dist: apache-airflow-providers-celery==3.20.0; extra == "frozen"
|
|
91
92
|
Requires-Dist: apache-airflow-providers-common-compat==1.15.0; extra == "frozen"
|
|
92
93
|
Requires-Dist: apache-airflow-providers-common-io==1.7.3; extra == "frozen"
|
|
93
94
|
Requires-Dist: apache-airflow-providers-common-sql==2.0.1; extra == "frozen"
|
|
94
|
-
Requires-Dist: apache-airflow-providers-postgres==6.
|
|
95
|
+
Requires-Dist: apache-airflow-providers-postgres==6.8.0; extra == "frozen"
|
|
95
96
|
Requires-Dist: apache-airflow-providers-smtp==3.0.1; extra == "frozen"
|
|
96
|
-
Requires-Dist: apache-airflow-providers-standard==1.
|
|
97
|
+
Requires-Dist: apache-airflow-providers-standard==1.15.0; extra == "frozen"
|
|
97
98
|
Requires-Dist: apache-airflow-task-sdk==1.2.1; extra == "frozen"
|
|
98
|
-
Requires-Dist: appnope==0.1.4; extra == "frozen"
|
|
99
99
|
Requires-Dist: argcomplete==3.6.3; extra == "frozen"
|
|
100
100
|
Requires-Dist: argon2-cffi==25.1.0; extra == "frozen"
|
|
101
101
|
Requires-Dist: argon2-cffi-bindings==25.1.0; extra == "frozen"
|
|
@@ -114,14 +114,14 @@ Requires-Dist: babel==2.18.0; extra == "frozen"
|
|
|
114
114
|
Requires-Dist: beautifulsoup4==4.15.0; extra == "frozen"
|
|
115
115
|
Requires-Dist: billiard==4.2.4; extra == "frozen"
|
|
116
116
|
Requires-Dist: bleach==6.4.0; extra == "frozen"
|
|
117
|
-
Requires-Dist: boto3==1.43.
|
|
118
|
-
Requires-Dist: botocore==1.43.
|
|
117
|
+
Requires-Dist: boto3==1.43.36; extra == "frozen"
|
|
118
|
+
Requires-Dist: botocore==1.43.36; extra == "frozen"
|
|
119
119
|
Requires-Dist: cadwyn==7.1.0; extra == "frozen"
|
|
120
120
|
Requires-Dist: celery==5.6.3; extra == "frozen"
|
|
121
121
|
Requires-Dist: certifi==2026.6.17; extra == "frozen"
|
|
122
122
|
Requires-Dist: cffi==2.0.0; extra == "frozen"
|
|
123
123
|
Requires-Dist: charset-normalizer==3.4.7; extra == "frozen"
|
|
124
|
-
Requires-Dist: click==8.4.
|
|
124
|
+
Requires-Dist: click==8.4.2; extra == "frozen"
|
|
125
125
|
Requires-Dist: click-didyoumean==0.3.1; extra == "frozen"
|
|
126
126
|
Requires-Dist: click-plugins==1.1.1.2; extra == "frozen"
|
|
127
127
|
Requires-Dist: click-repl==0.3.0; extra == "frozen"
|
|
@@ -139,7 +139,7 @@ Requires-Dist: dill==0.4.1; extra == "frozen"
|
|
|
139
139
|
Requires-Dist: dkist-header-validator==5.4.0; extra == "frozen"
|
|
140
140
|
Requires-Dist: dkist-processing-common==14.3.4; extra == "frozen"
|
|
141
141
|
Requires-Dist: dkist-processing-core==7.3.0; extra == "frozen"
|
|
142
|
-
Requires-Dist: dkist-processing-cryonirsp==
|
|
142
|
+
Requires-Dist: dkist-processing-cryonirsp==2.0.0rc2; extra == "frozen"
|
|
143
143
|
Requires-Dist: dkist-processing-math==2.2.3; extra == "frozen"
|
|
144
144
|
Requires-Dist: dkist-processing-pac==3.1.2; extra == "frozen"
|
|
145
145
|
Requires-Dist: dkist-service-configuration==4.3.0; extra == "frozen"
|
|
@@ -148,7 +148,7 @@ Requires-Dist: dkist_fits_specifications==4.28.0; extra == "frozen"
|
|
|
148
148
|
Requires-Dist: dnspython==2.8.0; extra == "frozen"
|
|
149
149
|
Requires-Dist: email-validator==2.3.0; extra == "frozen"
|
|
150
150
|
Requires-Dist: executing==2.2.1; extra == "frozen"
|
|
151
|
-
Requires-Dist: fastapi==0.138.
|
|
151
|
+
Requires-Dist: fastapi==0.138.1; extra == "frozen"
|
|
152
152
|
Requires-Dist: fastapi-cli==0.0.27; extra == "frozen"
|
|
153
153
|
Requires-Dist: fastjsonschema==2.21.2; extra == "frozen"
|
|
154
154
|
Requires-Dist: flower==2.0.1; extra == "frozen"
|
|
@@ -177,6 +177,7 @@ Requires-Dist: isoduration==20.11.0; extra == "frozen"
|
|
|
177
177
|
Requires-Dist: itsdangerous==2.2.0; extra == "frozen"
|
|
178
178
|
Requires-Dist: jedi==0.20.0; extra == "frozen"
|
|
179
179
|
Requires-Dist: jmespath==1.1.0; extra == "frozen"
|
|
180
|
+
Requires-Dist: joblib==1.5.3; extra == "frozen"
|
|
180
181
|
Requires-Dist: json5==0.15.0; extra == "frozen"
|
|
181
182
|
Requires-Dist: jsonpointer==3.1.1; extra == "frozen"
|
|
182
183
|
Requires-Dist: jsonschema==4.26.0; extra == "frozen"
|
|
@@ -208,11 +209,12 @@ Requires-Dist: matplotlib==3.11.0; extra == "frozen"
|
|
|
208
209
|
Requires-Dist: matplotlib-inline==0.2.2; extra == "frozen"
|
|
209
210
|
Requires-Dist: mdurl==0.1.2; extra == "frozen"
|
|
210
211
|
Requires-Dist: methodtools==0.4.7; extra == "frozen"
|
|
211
|
-
Requires-Dist: mistune==3.3.
|
|
212
|
+
Requires-Dist: mistune==3.3.2; extra == "frozen"
|
|
212
213
|
Requires-Dist: more-itertools==11.1.0; extra == "frozen"
|
|
213
214
|
Requires-Dist: moviepy==2.1.2; extra == "frozen"
|
|
214
215
|
Requires-Dist: msgspec==0.21.1; extra == "frozen"
|
|
215
216
|
Requires-Dist: multidict==6.7.1; extra == "frozen"
|
|
217
|
+
Requires-Dist: narwhals==2.22.1; extra == "frozen"
|
|
216
218
|
Requires-Dist: natsort==8.4.0; extra == "frozen"
|
|
217
219
|
Requires-Dist: nbclient==0.11.0; extra == "frozen"
|
|
218
220
|
Requires-Dist: nbconvert==7.17.1; extra == "frozen"
|
|
@@ -224,30 +226,30 @@ Requires-Dist: notebook_shim==0.2.4; extra == "frozen"
|
|
|
224
226
|
Requires-Dist: numba==0.61.2; extra == "frozen"
|
|
225
227
|
Requires-Dist: numpy==2.2.5; extra == "frozen"
|
|
226
228
|
Requires-Dist: object-clerk==1.0.0; extra == "frozen"
|
|
227
|
-
Requires-Dist: opentelemetry-api==1.
|
|
228
|
-
Requires-Dist: opentelemetry-exporter-otlp==1.
|
|
229
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.
|
|
230
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc==1.
|
|
231
|
-
Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.
|
|
232
|
-
Requires-Dist: opentelemetry-instrumentation==0.
|
|
233
|
-
Requires-Dist: opentelemetry-instrumentation-aiohttp-client==0.
|
|
234
|
-
Requires-Dist: opentelemetry-instrumentation-asgi==0.
|
|
235
|
-
Requires-Dist: opentelemetry-instrumentation-botocore==0.
|
|
236
|
-
Requires-Dist: opentelemetry-instrumentation-celery==0.
|
|
237
|
-
Requires-Dist: opentelemetry-instrumentation-dbapi==0.
|
|
238
|
-
Requires-Dist: opentelemetry-instrumentation-fastapi==0.
|
|
239
|
-
Requires-Dist: opentelemetry-instrumentation-pika==0.
|
|
240
|
-
Requires-Dist: opentelemetry-instrumentation-psycopg2==0.
|
|
241
|
-
Requires-Dist: opentelemetry-instrumentation-pymongo==0.
|
|
242
|
-
Requires-Dist: opentelemetry-instrumentation-redis==0.
|
|
243
|
-
Requires-Dist: opentelemetry-instrumentation-requests==0.
|
|
244
|
-
Requires-Dist: opentelemetry-instrumentation-sqlalchemy==0.
|
|
245
|
-
Requires-Dist: opentelemetry-instrumentation-system-metrics==0.
|
|
229
|
+
Requires-Dist: opentelemetry-api==1.43.0; extra == "frozen"
|
|
230
|
+
Requires-Dist: opentelemetry-exporter-otlp==1.43.0; extra == "frozen"
|
|
231
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.43.0; extra == "frozen"
|
|
232
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-grpc==1.43.0; extra == "frozen"
|
|
233
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.43.0; extra == "frozen"
|
|
234
|
+
Requires-Dist: opentelemetry-instrumentation==0.64b0; extra == "frozen"
|
|
235
|
+
Requires-Dist: opentelemetry-instrumentation-aiohttp-client==0.64b0; extra == "frozen"
|
|
236
|
+
Requires-Dist: opentelemetry-instrumentation-asgi==0.64b0; extra == "frozen"
|
|
237
|
+
Requires-Dist: opentelemetry-instrumentation-botocore==0.64b0; extra == "frozen"
|
|
238
|
+
Requires-Dist: opentelemetry-instrumentation-celery==0.64b0; extra == "frozen"
|
|
239
|
+
Requires-Dist: opentelemetry-instrumentation-dbapi==0.64b0; extra == "frozen"
|
|
240
|
+
Requires-Dist: opentelemetry-instrumentation-fastapi==0.64b0; extra == "frozen"
|
|
241
|
+
Requires-Dist: opentelemetry-instrumentation-pika==0.64b0; extra == "frozen"
|
|
242
|
+
Requires-Dist: opentelemetry-instrumentation-psycopg2==0.64b0; extra == "frozen"
|
|
243
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo==0.64b0; extra == "frozen"
|
|
244
|
+
Requires-Dist: opentelemetry-instrumentation-redis==0.64b0; extra == "frozen"
|
|
245
|
+
Requires-Dist: opentelemetry-instrumentation-requests==0.64b0; extra == "frozen"
|
|
246
|
+
Requires-Dist: opentelemetry-instrumentation-sqlalchemy==0.64b0; extra == "frozen"
|
|
247
|
+
Requires-Dist: opentelemetry-instrumentation-system-metrics==0.64b0; extra == "frozen"
|
|
246
248
|
Requires-Dist: opentelemetry-propagator-aws-xray==1.0.2; extra == "frozen"
|
|
247
|
-
Requires-Dist: opentelemetry-proto==1.
|
|
248
|
-
Requires-Dist: opentelemetry-sdk==1.
|
|
249
|
-
Requires-Dist: opentelemetry-semantic-conventions==0.
|
|
250
|
-
Requires-Dist: opentelemetry-util-http==0.
|
|
249
|
+
Requires-Dist: opentelemetry-proto==1.43.0; extra == "frozen"
|
|
250
|
+
Requires-Dist: opentelemetry-sdk==1.43.0; extra == "frozen"
|
|
251
|
+
Requires-Dist: opentelemetry-semantic-conventions==0.64b0; extra == "frozen"
|
|
252
|
+
Requires-Dist: opentelemetry-util-http==0.64b0; extra == "frozen"
|
|
251
253
|
Requires-Dist: outcome==1.3.0.post0; extra == "frozen"
|
|
252
254
|
Requires-Dist: packaging==26.2; extra == "frozen"
|
|
253
255
|
Requires-Dist: pandas==3.0.3; extra == "frozen"
|
|
@@ -268,7 +270,7 @@ Requires-Dist: proglog==0.1.12; extra == "frozen"
|
|
|
268
270
|
Requires-Dist: prometheus_client==0.25.0; extra == "frozen"
|
|
269
271
|
Requires-Dist: prompt_toolkit==3.0.52; extra == "frozen"
|
|
270
272
|
Requires-Dist: propcache==0.5.2; extra == "frozen"
|
|
271
|
-
Requires-Dist: protobuf==
|
|
273
|
+
Requires-Dist: protobuf==7.35.1; extra == "frozen"
|
|
272
274
|
Requires-Dist: psutil==7.2.2; extra == "frozen"
|
|
273
275
|
Requires-Dist: psycopg2-binary==2.9.12; extra == "frozen"
|
|
274
276
|
Requires-Dist: ptyprocess==0.7.0; extra == "frozen"
|
|
@@ -301,6 +303,7 @@ Requires-Dist: rich-toolkit==0.20.1; extra == "frozen"
|
|
|
301
303
|
Requires-Dist: rpds-py==2026.5.1; extra == "frozen"
|
|
302
304
|
Requires-Dist: s3transfer==0.19.0; extra == "frozen"
|
|
303
305
|
Requires-Dist: scikit-image==0.25.2; extra == "frozen"
|
|
306
|
+
Requires-Dist: scikit-learn==1.9.0; extra == "frozen"
|
|
304
307
|
Requires-Dist: scipy==1.15.3; extra == "frozen"
|
|
305
308
|
Requires-Dist: semantic-version==2.10.0; extra == "frozen"
|
|
306
309
|
Requires-Dist: setproctitle==1.3.7; extra == "frozen"
|
|
@@ -322,6 +325,7 @@ Requires-Dist: tenacity==8.5.0; extra == "frozen"
|
|
|
322
325
|
Requires-Dist: termcolor==3.3.0; extra == "frozen"
|
|
323
326
|
Requires-Dist: terminado==0.18.1; extra == "frozen"
|
|
324
327
|
Requires-Dist: text-unidecode==1.3; extra == "frozen"
|
|
328
|
+
Requires-Dist: threadpoolctl==3.6.0; extra == "frozen"
|
|
325
329
|
Requires-Dist: tifffile==2026.6.1; extra == "frozen"
|
|
326
330
|
Requires-Dist: tinycss2==1.5.1; extra == "frozen"
|
|
327
331
|
Requires-Dist: tornado==6.5.7; extra == "frozen"
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
The calculation of a single spectral shift is now *only* via interpolation of the correlation signal between the reference
|
|
2
|
+
and target spectra. Previously a second refinement of this value was done via a chi-squared minimization, but this was show
|
|
3
|
+
to increase noise with no increase in accuracy.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
Add option to all local trial workflows (``--parameter-doc``) that uses an existing input dataset parameter-part document
|
|
2
|
+
to populate the parameters during a local run. This is an easy way for a user to run a pipeline locally using the exact
|
|
3
|
+
parameters used in production.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
Improvements to the calculation of the spectral curvature to make them more robust against noisy input data. This change
|
|
2
|
+
only affects science data for datasets where the spectral curvature was previously mis-identified. For these datasets this
|
|
3
|
+
change will correct un-aligned spectral axes in L1 data and improve the quality of gain correction because the solar gain
|
|
4
|
+
frames will have better removal of solar absorption lines.
|
|
@@ -37,11 +37,36 @@ class CryonirspParameters(ParameterBase, ParameterWavelengthMixin, ParameterArmI
|
|
|
37
37
|
"""Pixel precision (1/upsample_factor) to use during phase matching of beam/modulator images."""
|
|
38
38
|
return self._find_most_recent_past_value("cryonirsp_geo_upsample_factor")
|
|
39
39
|
|
|
40
|
+
@property
|
|
41
|
+
def geo_savgol_window_length_px(self) -> int:
|
|
42
|
+
"""Size of the window for the SavGol filter used to smooth the spectral derivative during prep for spectral shift measurements."""
|
|
43
|
+
return self._find_most_recent_past_value("cryonirsp_geo_savgol_window_length_px")
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def geo_savgol_polyorder(self) -> int:
|
|
47
|
+
"""Order of the polynomial fit in the SavGol filter used to smooth the spectral derivative during prep for the spectral shift measurements."""
|
|
48
|
+
return self._find_most_recent_past_value("cryonirsp_geo_savgol_polyorder")
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def geo_derivative_cutoff_threshold(self) -> float:
|
|
52
|
+
"""Threshold value for the spectral derivative above which pixels will be set to NaN."""
|
|
53
|
+
return self._find_most_recent_past_value("cryonirsp_geo_derivative_cutoff_threshold")
|
|
54
|
+
|
|
40
55
|
@property
|
|
41
56
|
def geo_max_shift(self) -> int:
|
|
42
57
|
"""Max allowed pixel shift when computing spectral curvature."""
|
|
43
58
|
return self._find_most_recent_past_value("cryonirsp_geo_max_shift")
|
|
44
59
|
|
|
60
|
+
@property
|
|
61
|
+
def geo_shift_peak_interpolation_width_px(self) -> int:
|
|
62
|
+
"""Return the ± pixel width used to interpolate the correlation peaks when computing spectral curvature."""
|
|
63
|
+
return self._find_most_recent_past_value("cryonirsp_geo_shift_peak_interpolation_width_px")
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def geo_poly_fit_min_samples(self) -> float:
|
|
67
|
+
"""Return fractional number of samples required for the RANSAC regressor used to fit spectral shifts along the slit."""
|
|
68
|
+
return self._find_most_recent_past_value("cryonirsp_geo_poly_fit_min_samples")
|
|
69
|
+
|
|
45
70
|
@property
|
|
46
71
|
def geo_poly_fit_order(self) -> int:
|
|
47
72
|
"""Order of polynomial used to fit spectral shift as a function of slit position."""
|
|
@@ -12,6 +12,7 @@ from dkist_processing_math.arithmetic import divide_arrays_by_array
|
|
|
12
12
|
from dkist_processing_math.arithmetic import subtract_array_from_arrays
|
|
13
13
|
from dkist_processing_math.statistics import average_numpy_arrays
|
|
14
14
|
from dkist_processing_math.transform.binning import resize_arrays
|
|
15
|
+
from dkist_processing_math.transform.binning import resize_arrays_local_mean
|
|
15
16
|
from dkist_processing_pac.fitter.polcal_fitter import PolcalFitter
|
|
16
17
|
from dkist_processing_pac.input_data.drawer import Drawer
|
|
17
18
|
from dkist_processing_pac.input_data.dresser import Dresser
|
|
@@ -281,8 +282,8 @@ class InstrumentPolarizationCalibrationBase(CryonirspTaskBase, ABC):
|
|
|
281
282
|
self.parameters.polcal_num_spatial_bins,
|
|
282
283
|
self.parameters.polcal_num_spectral_bins,
|
|
283
284
|
)
|
|
284
|
-
local_binned_array = next(
|
|
285
|
-
global_binned_array = next(
|
|
285
|
+
local_binned_array = next(resize_arrays_local_mean(gain_corrected_array, output_shape))
|
|
286
|
+
global_binned_array = next(resize_arrays_local_mean(gain_corrected_array, (1, 1)))
|
|
286
287
|
|
|
287
288
|
with self.telemetry_span(f"Create reduced CryonirspL0FitsAccess for {apm_str}"):
|
|
288
289
|
local_result = CryonirspL0FitsAccess(
|
|
@@ -4,14 +4,20 @@ import math
|
|
|
4
4
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import peakutils as pku
|
|
7
|
+
import scipy.interpolate as spi
|
|
7
8
|
import scipy.ndimage as spnd
|
|
9
|
+
import scipy.signal as ss
|
|
8
10
|
from dkist_processing_common.codecs.fits import fits_array_encoder
|
|
9
11
|
from dkist_processing_common.models.task_name import TaskName
|
|
10
12
|
from dkist_processing_math.arithmetic import divide_arrays_by_array
|
|
11
13
|
from dkist_processing_math.arithmetic import subtract_array_from_arrays
|
|
12
14
|
from dkist_processing_math.statistics import average_numpy_arrays
|
|
13
15
|
from dkist_service_configuration.logging import logger
|
|
14
|
-
from
|
|
16
|
+
from sklearn.linear_model import RANSACRegressor
|
|
17
|
+
from sklearn.pipeline import Pipeline
|
|
18
|
+
from sklearn.pipeline import make_pipeline
|
|
19
|
+
from sklearn.preprocessing import PolynomialFeatures
|
|
20
|
+
from sklearn.preprocessing import RobustScaler
|
|
15
21
|
|
|
16
22
|
from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
|
|
17
23
|
from dkist_processing_cryonirsp.models.beam_boundaries import BeamBoundary
|
|
@@ -97,6 +103,9 @@ class SPGeometricCalibration(CryonirspTaskBase, ShiftMeasurementsMixin):
|
|
|
97
103
|
beam=beam,
|
|
98
104
|
)
|
|
99
105
|
|
|
106
|
+
with self.telemetry_span(f"Preparing beam {beam} for spectral shift measurement"):
|
|
107
|
+
self.prepare_array_for_shift_measurement(beam=beam)
|
|
108
|
+
|
|
100
109
|
with self.telemetry_span(f"Computing spectral shifts for {beam = }"):
|
|
101
110
|
spec_shifts = self.compute_spectral_shifts(beam=beam)
|
|
102
111
|
|
|
@@ -181,6 +190,22 @@ class SPGeometricCalibration(CryonirspTaskBase, ShiftMeasurementsMixin):
|
|
|
181
190
|
)
|
|
182
191
|
return average_numpy_arrays(array_generator)
|
|
183
192
|
|
|
193
|
+
def shift_prepared_data(self, beam: int) -> np.ndarray:
|
|
194
|
+
"""
|
|
195
|
+
Array for a single beam that has been prepared for measurements of spectral shift.
|
|
196
|
+
|
|
197
|
+
I.e., the array created by `prepare_array_for_spectral_shift`
|
|
198
|
+
"""
|
|
199
|
+
return next(
|
|
200
|
+
self.read(
|
|
201
|
+
tags=[
|
|
202
|
+
CryonirspTag.intermediate_frame(beam=beam),
|
|
203
|
+
CryonirspTag.task("GC_SHIFT_PREPARED"),
|
|
204
|
+
],
|
|
205
|
+
decoder=cryo_fits_array_decoder,
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
|
|
184
209
|
def do_basic_corrections(self):
|
|
185
210
|
"""Apply dark, bad pixel and lamp gain corrections to all data that will be used for Geometric Calibration."""
|
|
186
211
|
# There is likely only a single exposure conditions tuple in the list, but we iterate over the list
|
|
@@ -415,11 +440,11 @@ class SPGeometricCalibration(CryonirspTaskBase, ShiftMeasurementsMixin):
|
|
|
415
440
|
I.e., the spectral shift at each slit position needed to have wavelength be constant across a single spatial
|
|
416
441
|
pixel. Generally, the algorithm is:
|
|
417
442
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
443
|
+
#. Identify the reference array spectrum as the center of the slit
|
|
444
|
+
#. For each slit position, measure the shift by cross-correlating the spectrum with the reference spectrum
|
|
445
|
+
#. Mask spatial pixels with large RMS differences between the reference spectrum and their shifted spectra
|
|
446
|
+
#. Fit a polynomial to the measured shifts as a function of slit position
|
|
447
|
+
#. Remove the mean shift so the total shift amount is minimized
|
|
423
448
|
|
|
424
449
|
Parameters
|
|
425
450
|
----------
|
|
@@ -432,32 +457,39 @@ class SPGeometricCalibration(CryonirspTaskBase, ShiftMeasurementsMixin):
|
|
|
432
457
|
Spectral shift for a single beam
|
|
433
458
|
"""
|
|
434
459
|
logger.info(f"Computing spectral shifts for beam {beam}")
|
|
435
|
-
beam_array = self.
|
|
460
|
+
beam_array = self.shift_prepared_data(beam=beam)
|
|
436
461
|
spatial_size = beam_array.shape[0]
|
|
437
462
|
|
|
438
463
|
if beam == 1:
|
|
439
464
|
# Use the same reference spectrum for both beams.
|
|
440
465
|
# We pick the spectrum from the center of the slit, with a buffer of 10 pixels on either side
|
|
441
466
|
middle_row = spatial_size // 2
|
|
442
|
-
|
|
467
|
+
raw_ref_spec = np.nanmedian(beam_array[middle_row - 10 : middle_row + 10, :], axis=0)
|
|
468
|
+
cleaned_ref_spec = self.clean_spectrum(spectrum=raw_ref_spec)
|
|
469
|
+
self.ref_spec = cleaned_ref_spec
|
|
443
470
|
|
|
444
|
-
beam_shifts = np.
|
|
471
|
+
beam_shifts = np.full(spatial_size, np.nan)
|
|
472
|
+
beam_rms = np.full(spatial_size, np.nan)
|
|
445
473
|
for i in range(spatial_size):
|
|
446
|
-
target_spec = beam_array[i, :]
|
|
474
|
+
target_spec = self.clean_spectrum(spectrum=beam_array[i, :])
|
|
447
475
|
|
|
448
|
-
|
|
476
|
+
shift = self.compute_single_spec_shift(
|
|
449
477
|
ref_spec=self.ref_spec, target_spec=target_spec, beam=beam, pos=i
|
|
450
478
|
)
|
|
451
479
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
target_spec=target_spec,
|
|
455
|
-
initial_guess=initial_guess,
|
|
456
|
-
beam=beam,
|
|
457
|
-
pos=i,
|
|
458
|
-
)
|
|
480
|
+
shifted_target = spnd.shift(target_spec, -shift, cval=np.nan)
|
|
481
|
+
rms = np.nanstd(self.ref_spec - shifted_target)
|
|
459
482
|
|
|
460
483
|
beam_shifts[i] = shift
|
|
484
|
+
beam_rms[i] = rms
|
|
485
|
+
|
|
486
|
+
# Mask spatial positions with large residuals even after applying the measured shift
|
|
487
|
+
# Setting the threshold as 4 times the second quartile amount is a good way to estimate are large
|
|
488
|
+
# fraction of the CDF from a region that won't be polluted with outliers.
|
|
489
|
+
rms_median, rms_25_percentile = np.nanpercentile(beam_rms, [50, 25])
|
|
490
|
+
rms_threshold = rms_median + 4 * (rms_median - rms_25_percentile)
|
|
491
|
+
logger.info(f"Raw shift RMS threshold for beam {beam} is {rms_threshold}")
|
|
492
|
+
beam_shifts[beam_rms > rms_threshold] = np.nan
|
|
461
493
|
|
|
462
494
|
# Subtract the average so we shift my a minimal amount
|
|
463
495
|
if beam == 1:
|
|
@@ -477,22 +509,95 @@ class SPGeometricCalibration(CryonirspTaskBase, ShiftMeasurementsMixin):
|
|
|
477
509
|
|
|
478
510
|
# Finally, fit the shifts and return the resulting polynomial. Any "bad" fits were set to NaN and will be
|
|
479
511
|
# interpolated over.
|
|
480
|
-
poly_fit_order = self.parameters.geo_poly_fit_order
|
|
481
512
|
nan_idx = np.isnan(beam_shifts)
|
|
482
|
-
|
|
483
|
-
|
|
513
|
+
ransac_abscissa = np.arange(spatial_size)[:, None]
|
|
514
|
+
model = self.build_RANSAC_model()
|
|
515
|
+
model.fit(ransac_abscissa[~nan_idx, :], beam_shifts[~nan_idx])
|
|
516
|
+
|
|
517
|
+
return model.predict(ransac_abscissa)
|
|
518
|
+
|
|
519
|
+
def prepare_array_for_shift_measurement(self, beam: int) -> None:
|
|
520
|
+
"""
|
|
521
|
+
Apply filtering to an array to amplify the spectral signal and improve subsequent shift measurements.
|
|
522
|
+
|
|
523
|
+
The array to be filtered is the fully offset-and-angle corrected array for the given beam.
|
|
524
|
+
|
|
525
|
+
The filtering steps are:
|
|
526
|
+
|
|
527
|
+
#. Normalize each spectral pixel by a fixed value of its CDF. This removes scaling differences between the reference and target spectra.
|
|
528
|
+
|
|
529
|
+
a. At this stage we also clip values outside the range [0, 2]
|
|
530
|
+
|
|
531
|
+
#. Computed a smoothed spectral derivative for each spatial pixel. This step greatly increases the strength of the true spectral signal.
|
|
532
|
+
|
|
533
|
+
#. Apply a spectral windowing function to protect the correlation of the reference and target spectra from weird and wild edge-effects.
|
|
534
|
+
"""
|
|
535
|
+
beam_array = self.offset_corrected_data(beam=beam)
|
|
536
|
+
|
|
537
|
+
normalized = (
|
|
538
|
+
beam_array
|
|
539
|
+
/ np.nanpercentile(
|
|
540
|
+
beam_array,
|
|
541
|
+
self.parameters.solar_characteristic_spatial_normalization_percentile,
|
|
542
|
+
axis=1,
|
|
543
|
+
)[:, None]
|
|
544
|
+
)
|
|
545
|
+
|
|
546
|
+
# The normalized array really shouldn't have any values less than 0 or more than 2; we're essentially
|
|
547
|
+
# saying we expect the dynamic range of the spectrum to be less than 200% of the continuum value, which
|
|
548
|
+
# is a very reasonable assumption.
|
|
549
|
+
clipped = np.clip(normalized, 0, 2)
|
|
550
|
+
|
|
551
|
+
# Compute a smoothed derivative in one step with the `deriv` kwarg to `savgol_filter`
|
|
552
|
+
smoothed_derivative = ss.savgol_filter(
|
|
553
|
+
clipped,
|
|
554
|
+
window_length=self.parameters.geo_savgol_window_length_px,
|
|
555
|
+
polyorder=self.parameters.geo_savgol_polyorder,
|
|
556
|
+
deriv=1,
|
|
557
|
+
axis=1,
|
|
484
558
|
)
|
|
485
559
|
|
|
486
|
-
|
|
560
|
+
# Apply a window to reduce bad edge signals. This works because the mean of the derivative should be 0.
|
|
561
|
+
windowed = smoothed_derivative * ss.windows.tukey(smoothed_derivative.shape[1])[None, :]
|
|
562
|
+
windowed[np.abs(windowed) > self.parameters.geo_derivative_cutoff_threshold] = np.nan
|
|
487
563
|
|
|
488
|
-
|
|
564
|
+
self.write(
|
|
565
|
+
data=windowed,
|
|
566
|
+
tags=[
|
|
567
|
+
CryonirspTag.intermediate_frame(beam=beam),
|
|
568
|
+
CryonirspTag.task("GC_SHIFT_PREPARED"),
|
|
569
|
+
],
|
|
570
|
+
encoder=fits_array_encoder,
|
|
571
|
+
)
|
|
572
|
+
|
|
573
|
+
def clean_spectrum(self, spectrum: np.ndarray) -> np.ndarray:
|
|
574
|
+
"""
|
|
575
|
+
Clean non-finite pixels in a spectrum by interpolating over them.
|
|
576
|
+
|
|
577
|
+
Interpolation is done via nearest-neighbor and any extrapolated values are set to the mean of the
|
|
578
|
+
spectrum so that they don't contribute any signal to `compute_single_spec_shift`.
|
|
579
|
+
"""
|
|
580
|
+
bad_mask = ~np.isfinite(spectrum)
|
|
581
|
+
abscissa = np.arange(spectrum.size)
|
|
582
|
+
interp_func = spi.interp1d(
|
|
583
|
+
abscissa[~bad_mask],
|
|
584
|
+
spectrum[~bad_mask],
|
|
585
|
+
kind="nearest",
|
|
586
|
+
bounds_error=False,
|
|
587
|
+
fill_value=np.mean(spectrum[~bad_mask]),
|
|
588
|
+
)
|
|
589
|
+
spectrum[bad_mask] = interp_func(abscissa[bad_mask])
|
|
590
|
+
return spectrum
|
|
591
|
+
|
|
592
|
+
def compute_single_spec_shift(
|
|
489
593
|
self, *, ref_spec: np.ndarray, target_spec: np.ndarray, beam: int, pos: int
|
|
490
594
|
) -> float:
|
|
491
595
|
"""
|
|
492
|
-
|
|
596
|
+
Compute the offset between two spectra via correlation.
|
|
493
597
|
|
|
494
|
-
A basic correlation is performed and the location of the peak
|
|
495
|
-
peak is found then the peak
|
|
598
|
+
A basic correlation is performed and the location of the correlation peak is the shift. The true peak is found
|
|
599
|
+
by interpolating around the maximum correlation location. If more than one strong peak is found then the peak
|
|
600
|
+
locations are averaged together.
|
|
496
601
|
"""
|
|
497
602
|
corr = np.correlate(
|
|
498
603
|
target_spec - np.nanmean(target_spec),
|
|
@@ -507,84 +612,59 @@ class SPGeometricCalibration(CryonirspTaskBase, ShiftMeasurementsMixin):
|
|
|
507
612
|
truncated_corr = corr[start:stop]
|
|
508
613
|
|
|
509
614
|
# This min_dist ensures we only find a single peak in each correlation signal
|
|
510
|
-
|
|
511
|
-
initial_guess = 1 * (pidx - truncated_corr.size // 2)
|
|
615
|
+
peak_idx = pku.indexes(truncated_corr, min_dist=truncated_corr.size)
|
|
512
616
|
|
|
513
|
-
#
|
|
514
|
-
if
|
|
617
|
+
# This edge-case is very rare, but does happen sometimes
|
|
618
|
+
if peak_idx.size != 1:
|
|
515
619
|
logger.info(
|
|
516
|
-
f"Spatial position {pos} in {beam=}
|
|
620
|
+
f"Spatial position {pos} in {beam = } has either no or multiple correlation peaks. Shift set to NaN."
|
|
517
621
|
)
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
622
|
+
return np.nan
|
|
623
|
+
|
|
624
|
+
try:
|
|
625
|
+
peak_interp = pku.interpolate(
|
|
626
|
+
np.arange(truncated_corr.size),
|
|
627
|
+
truncated_corr,
|
|
628
|
+
ind=peak_idx,
|
|
629
|
+
width=self.parameters.geo_shift_peak_interpolation_width_px,
|
|
630
|
+
)
|
|
631
|
+
except:
|
|
521
632
|
logger.info(
|
|
522
|
-
f"Spatial position {pos} in {beam=}
|
|
633
|
+
f"Spatial position {pos} in {beam = } failed to interpolate the correlation peak. Falling back "
|
|
634
|
+
"to the rough peak."
|
|
523
635
|
)
|
|
524
|
-
|
|
636
|
+
peak_interp = peak_idx[0]
|
|
525
637
|
|
|
526
|
-
|
|
638
|
+
shift = 1 * (peak_interp - truncated_corr.size // 2)
|
|
527
639
|
|
|
528
|
-
|
|
529
|
-
self,
|
|
530
|
-
*,
|
|
531
|
-
ref_spec: np.ndarray,
|
|
532
|
-
target_spec: np.ndarray,
|
|
533
|
-
initial_guess: float,
|
|
534
|
-
beam: int,
|
|
535
|
-
pos: int,
|
|
536
|
-
) -> float:
|
|
537
|
-
"""
|
|
538
|
-
Refine the 1D offset between two spectra.
|
|
640
|
+
return shift.item(0)
|
|
539
641
|
|
|
540
|
-
|
|
541
|
-
between the reference spectrum and shifted target spectrum.
|
|
642
|
+
def build_RANSAC_model(self) -> Pipeline:
|
|
542
643
|
"""
|
|
543
|
-
|
|
544
|
-
self.shift_chisq,
|
|
545
|
-
np.atleast_1d(initial_guess),
|
|
546
|
-
args=(ref_spec, target_spec),
|
|
547
|
-
method="nelder-mead",
|
|
548
|
-
).x[0]
|
|
549
|
-
|
|
550
|
-
max_shift = self.parameters.geo_max_shift
|
|
551
|
-
if np.abs(shift) > max_shift:
|
|
552
|
-
# Didn't find a good peak
|
|
553
|
-
logger.info(
|
|
554
|
-
f"shift in {beam = } at spatial pixel {pos} out of range ({shift} > {max_shift})"
|
|
555
|
-
)
|
|
556
|
-
shift = np.nan
|
|
644
|
+
Build a scikit-learn pipeline from a set of estimators.
|
|
557
645
|
|
|
558
|
-
|
|
646
|
+
Namely, construct a `~sklearn.pipeline.Pipeline` built from
|
|
559
647
|
|
|
560
|
-
|
|
561
|
-
def shift_chisq(par: np.ndarray, ref_spec: np.ndarray, spec: np.ndarray) -> float:
|
|
648
|
+
`~sklearn.preprocessing.PolynomialFeatures` -> `~sklearn.preprocessing.RobustScaler` -> `~sklearn.linear_model.RANSACRegressor`
|
|
562
649
|
"""
|
|
563
|
-
|
|
650
|
+
fit_order = self.parameters.geo_poly_fit_order
|
|
651
|
+
min_samples = self.parameters.geo_poly_fit_min_samples
|
|
652
|
+
logger.info(f"Building RANSAC model with {fit_order = } and {min_samples = }")
|
|
564
653
|
|
|
565
|
-
|
|
654
|
+
# PolynomialFeatures casts the pipeline as a polynomial fit
|
|
655
|
+
# see https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.PolynomialFeatures.html#sklearn.preprocessing.PolynomialFeatures
|
|
656
|
+
poly_feature = PolynomialFeatures(degree=fit_order)
|
|
566
657
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
Spectral shift being optimized
|
|
658
|
+
# RobustScaler is a scale factor that is robust to outliers
|
|
659
|
+
# see https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.RobustScaler.html#sklearn.preprocessing.RobustScaler
|
|
660
|
+
scaler = RobustScaler()
|
|
571
661
|
|
|
572
|
-
|
|
573
|
-
|
|
662
|
+
# The RANSAC regressor iteratively sub-samples the input data and constructs a model with this sub-sample.
|
|
663
|
+
# The method used allows it to be robust to outliers.
|
|
664
|
+
# see https://scikit-learn.org/stable/modules/linear_model.html#ransac-regression
|
|
665
|
+
RANSAC = RANSACRegressor(min_samples=min_samples)
|
|
574
666
|
|
|
575
|
-
|
|
576
|
-
Spectra being fitted
|
|
577
|
-
|
|
578
|
-
Returns
|
|
579
|
-
-------
|
|
580
|
-
float
|
|
581
|
-
Sum of chisquared fit
|
|
582
|
-
|
|
583
|
-
"""
|
|
584
|
-
shift = par[0]
|
|
585
|
-
shifted_spec = spnd.shift(spec, -shift, mode="constant", cval=np.nan)
|
|
586
|
-
chisq = np.nansum((ref_spec - shifted_spec) ** 2 / ref_spec)
|
|
587
|
-
return chisq
|
|
667
|
+
return make_pipeline(poly_feature, scaler, RANSAC)
|
|
588
668
|
|
|
589
669
|
def write_angle(self, angle: float, beam: int) -> None:
|
|
590
670
|
"""
|
|
@@ -390,8 +390,13 @@ def cryonirsp_testing_parameters_factory(
|
|
|
390
390
|
cryonirsp_polcal_num_spectral_bins: int = 1
|
|
391
391
|
cryonirsp_polcal_pac_fit_mode: str = "use_M12_I_sys_per_step"
|
|
392
392
|
cryonirsp_geo_upsample_factor: int = 100
|
|
393
|
+
cryonirsp_geo_savgol_window_length_px: int = 15
|
|
394
|
+
cryonirsp_geo_savgol_polyorder: int = 3
|
|
395
|
+
cryonirsp_geo_derivative_cutoff_threshold: float = 0.2
|
|
393
396
|
cryonirsp_geo_max_shift: int = 80
|
|
394
|
-
|
|
397
|
+
cryonirsp_geo_shift_peak_interpolation_width_px: int = 5
|
|
398
|
+
cryonirsp_geo_poly_fit_min_samples: float = 0.6
|
|
399
|
+
cryonirsp_geo_poly_fit_order: int = 4
|
|
395
400
|
cryonirsp_geo_long_axis_gradient_displacement: int = 4
|
|
396
401
|
cryonirsp_geo_strip_long_axis_size_fraction: float = 0.8
|
|
397
402
|
cryonirsp_geo_strip_short_axis_size_fraction: float = 0.1
|