dkist-processing-common 10.2.2__tar.gz → 10.3.0__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_common-10.2.2 → dkist_processing_common-10.3.0}/CHANGELOG.rst +18 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/PKG-INFO +2 -2
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/quality/_metrics.py +88 -19
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/teardown.py +3 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/conftest.py +72 -12
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_assemble_quality.py +3 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_quality_mixin.py +79 -15
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_teardown.py +7 -7
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_workflow_task_base.py +7 -7
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common.egg-info/PKG-INFO +2 -2
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common.egg-info/requires.txt +1 -1
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/pyproject.toml +1 -1
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/.gitignore +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/.pre-commit-config.yaml +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/.readthedocs.yml +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/README.rst +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/bitbucket-pipelines.yml +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/changelog/.gitempty +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/check_changelog_updated.sh +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/_util/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/_util/constants.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/_util/graphql.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/_util/scratch.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/_util/tags.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/asdf.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/bytes.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/fits.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/iobase.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/json.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/path.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/quality.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/codecs/str.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/config.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/fonts/Lato-Regular.ttf +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/fonts/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/manual.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/constants.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/fits_access.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/flower_pot.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/graphql.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/message.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/message_queue_binding.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/metric_code.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/parameters.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/quality.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/tags.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/task_name.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/models/wavelength.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/cs_step.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/dsps_repeat.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/experiment_id_bud.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/id_bud.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/l0_fits_access.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/l1_fits_access.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/near_bud.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/proposal_id_bud.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/quality.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/single_value_single_key_flower.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/task.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/time.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/unique_bud.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/parsers/wavelength.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/assemble_movie.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/base.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/l1_output_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/globus.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/input_dataset.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/interservice_bus.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/metadata_store.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/object_store.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/quality/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/mixin/quality/_base.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/output_data_base.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/parse_l0_input_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/quality_metrics.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/transfer_input_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/trial_catalog.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/trial_output_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tasks/write_l1.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/__init__.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_assemble_movie.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_base.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_codecs.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_constants.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_cs_step.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_fits_access.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_flower_pot.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_input_dataset.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_interservice_bus.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_interservice_bus_mixin.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_output_data_base.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_parameters.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_parse_l0_input_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_publish_catalog_messages.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_quality.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_scratch.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_stems.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_submit_dataset_metadata.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_tags.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_task_name.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_task_parsing.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_transfer_input_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_transfer_l1_output_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_trial_catalog.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_trial_output_data.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common/tests/test_write_l1.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common.egg-info/SOURCES.txt +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common.egg-info/dependency_links.txt +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/dkist_processing_common.egg-info/top_level.txt +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/docs/Makefile +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/docs/changelog.rst +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/docs/conf.py +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/docs/index.rst +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/docs/make.bat +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/docs/requirements.txt +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/licenses/LICENSE.rst +0 -0
- {dkist_processing_common-10.2.2 → dkist_processing_common-10.3.0}/setup.cfg +0 -0
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
v10.3.0 (2024-10-15)
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
Features
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
- Update the machinery in `quality_store_polcal_results` to handle NaN values.
|
|
8
|
+
This is required for the new error-handling paradigm in `dkist-processing-pac` v3.1.0. (`#214 <https://bitbucket.org/dkistdc/dkist-processing-common/pull-requests/214>`__)
|
|
9
|
+
- Add new argument, `num_points_to_sample`, to `quality_store_polcal_results`, which allows a user to reduce the number of points saved for inclusion in the quality report.
|
|
10
|
+
This allows us to mitigate large quality metrics. (`#215 <https://bitbucket.org/dkistdc/dkist-processing-common/pull-requests/215>`__)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
Bugfixes
|
|
14
|
+
--------
|
|
15
|
+
|
|
16
|
+
- Correctly clean up tags used for file name uniqueness. (`#217 <https://bitbucket.org/dkistdc/dkist-processing-common/pull-requests/217>`__)
|
|
17
|
+
|
|
18
|
+
|
|
1
19
|
v10.2.2 (2024-10-14)
|
|
2
20
|
====================
|
|
3
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: dkist-processing-common
|
|
3
|
-
Version: 10.
|
|
3
|
+
Version: 10.3.0
|
|
4
4
|
Summary: Common task classes used by the DKIST science data processing pipelines
|
|
5
5
|
Author-email: NSO / AURA <dkistdc@nso.edu>
|
|
6
6
|
License: BSD-3-Clause
|
|
@@ -17,7 +17,7 @@ Requires-Dist: astropy>=5.1.1
|
|
|
17
17
|
Requires-Dist: dkist-fits-specifications<5.0,>=4.0.0
|
|
18
18
|
Requires-Dist: dkist-header-validator<6.0,>=5.0.0
|
|
19
19
|
Requires-Dist: dkist-processing-core==4.2.1
|
|
20
|
-
Requires-Dist: dkist-processing-pac<4.0,>=3.
|
|
20
|
+
Requires-Dist: dkist-processing-pac<4.0,>=3.1
|
|
21
21
|
Requires-Dist: dkist-service-configuration<3.0,>=2.0.2
|
|
22
22
|
Requires-Dist: dkist-spectral-lines<4.0,>=3.0.0
|
|
23
23
|
Requires-Dist: globus-sdk>=3.12.0
|
|
@@ -651,8 +651,11 @@ class _PolcalQualityMixin:
|
|
|
651
651
|
bin_nums: list[int],
|
|
652
652
|
bin_labels: list[str],
|
|
653
653
|
skip_recording_constant_pars: bool = False,
|
|
654
|
+
num_points_to_sample: int | None = None,
|
|
654
655
|
):
|
|
655
656
|
"""Compute and store all PolCal related metrics."""
|
|
657
|
+
thinning_stride = self._compute_thinning_stride(polcal_fitter, num_points_to_sample)
|
|
658
|
+
|
|
656
659
|
if not skip_recording_constant_pars:
|
|
657
660
|
logger.info("Storing constant parameter values")
|
|
658
661
|
self._store_polcal_constant_parameter_values(polcal_fitter=polcal_fitter, label=label)
|
|
@@ -662,7 +665,11 @@ class _PolcalQualityMixin:
|
|
|
662
665
|
|
|
663
666
|
logger.info("Storing local parameter values")
|
|
664
667
|
self._store_polcal_local_parameter_values(
|
|
665
|
-
polcal_fitter=polcal_fitter,
|
|
668
|
+
polcal_fitter=polcal_fitter,
|
|
669
|
+
label=label,
|
|
670
|
+
bin_nums=bin_nums,
|
|
671
|
+
bin_labels=bin_labels,
|
|
672
|
+
thinning_stride=thinning_stride,
|
|
666
673
|
)
|
|
667
674
|
|
|
668
675
|
logger.info("Storing fit residuals")
|
|
@@ -671,6 +678,7 @@ class _PolcalQualityMixin:
|
|
|
671
678
|
label=label,
|
|
672
679
|
bin_nums=bin_nums,
|
|
673
680
|
bin_labels=bin_labels,
|
|
681
|
+
thinning_stride=thinning_stride,
|
|
674
682
|
)
|
|
675
683
|
|
|
676
684
|
logger.info("Storing modulation matrix efficiencies")
|
|
@@ -679,6 +687,7 @@ class _PolcalQualityMixin:
|
|
|
679
687
|
label=label,
|
|
680
688
|
bin_nums=bin_nums,
|
|
681
689
|
bin_labels=bin_labels,
|
|
690
|
+
thinning_stride=thinning_stride,
|
|
682
691
|
)
|
|
683
692
|
|
|
684
693
|
@staticmethod
|
|
@@ -688,6 +697,32 @@ class _PolcalQualityMixin:
|
|
|
688
697
|
return None
|
|
689
698
|
return str(label).replace(" ", "_").upper()
|
|
690
699
|
|
|
700
|
+
@staticmethod
|
|
701
|
+
def _compute_thinning_stride(
|
|
702
|
+
polcal_fitter: PolcalFitter, num_points_to_sample: int
|
|
703
|
+
) -> int | None:
|
|
704
|
+
"""
|
|
705
|
+
Compute the stride needed to collect the requested number of data samples.
|
|
706
|
+
|
|
707
|
+
E.g., if there are 20,000 samples in the full `polcal_fitter` and the user wants to only save 200 then the
|
|
708
|
+
stride will be 100.
|
|
709
|
+
|
|
710
|
+
`None` is returned if no subsampling has been requested or if the number of requested samples is larger than
|
|
711
|
+
then number of samples in the full `polcal_fitter`.
|
|
712
|
+
"""
|
|
713
|
+
if num_points_to_sample is None:
|
|
714
|
+
return None
|
|
715
|
+
|
|
716
|
+
num_total_points = np.prod(polcal_fitter.local_objects.dresser.shape)
|
|
717
|
+
if num_points_to_sample > num_total_points:
|
|
718
|
+
return None
|
|
719
|
+
|
|
720
|
+
remainder = num_total_points % num_points_to_sample
|
|
721
|
+
if remainder:
|
|
722
|
+
return num_total_points // (num_points_to_sample - 1)
|
|
723
|
+
|
|
724
|
+
return num_total_points // num_points_to_sample
|
|
725
|
+
|
|
691
726
|
def _store_polcal_constant_parameter_values(
|
|
692
727
|
self, *, polcal_fitter: PolcalFitter, label: str
|
|
693
728
|
) -> None:
|
|
@@ -896,6 +931,7 @@ class _PolcalQualityMixin:
|
|
|
896
931
|
label: str,
|
|
897
932
|
bin_nums: list[int],
|
|
898
933
|
bin_labels: list[str],
|
|
934
|
+
thinning_stride: int | None,
|
|
899
935
|
) -> None:
|
|
900
936
|
"""Store local polcal parameter fits.
|
|
901
937
|
|
|
@@ -909,10 +945,16 @@ class _PolcalQualityMixin:
|
|
|
909
945
|
flattened_demod = np.reshape(
|
|
910
946
|
polcal_fitter.demodulation_matrices, (np.prod(fov_shape), 4, num_mod)
|
|
911
947
|
)
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
948
|
+
flattened_mod_list = []
|
|
949
|
+
# Need to apply stride this was (instead of argument to `range` because `range` doesn't accept `None` for
|
|
950
|
+
# step argument.
|
|
951
|
+
for i in range(flattened_demod.shape[0])[::thinning_stride]:
|
|
952
|
+
try:
|
|
953
|
+
flattened_mod_list.append(np.linalg.pinv(flattened_demod[i]))
|
|
954
|
+
except:
|
|
955
|
+
pass
|
|
915
956
|
|
|
957
|
+
flattened_mod = np.stack(flattened_mod_list)
|
|
916
958
|
# Move axis so numpoints is the last dimension, which will be easier to understand when
|
|
917
959
|
# plotting
|
|
918
960
|
flattened_mod = np.moveaxis(flattened_mod, 0, -1)
|
|
@@ -937,8 +979,10 @@ class _PolcalQualityMixin:
|
|
|
937
979
|
num_varied_I_sys += 1
|
|
938
980
|
|
|
939
981
|
fit_value_list = []
|
|
940
|
-
for point_param in fit_params._all_parameters:
|
|
941
|
-
|
|
982
|
+
for point_param in fit_params._all_parameters[::thinning_stride]:
|
|
983
|
+
value = point_param[param].value
|
|
984
|
+
if not np.isnan(value):
|
|
985
|
+
fit_value_list.append(value)
|
|
942
986
|
|
|
943
987
|
init_value = init_param.first_parameters[param].value
|
|
944
988
|
|
|
@@ -950,6 +994,7 @@ class _PolcalQualityMixin:
|
|
|
950
994
|
f"{num_bins} {bin_label}" for num_bins, bin_label in zip(bin_nums, bin_labels)
|
|
951
995
|
],
|
|
952
996
|
"total_bins": int(np.prod(bin_nums)),
|
|
997
|
+
"sampled_bins": flattened_mod.shape[-1],
|
|
953
998
|
"num_varied_I_sys": num_varied_I_sys,
|
|
954
999
|
"modmat_list": mod_list,
|
|
955
1000
|
"free_param_dict": free_param_data,
|
|
@@ -1005,7 +1050,9 @@ class _PolcalQualityMixin:
|
|
|
1005
1050
|
"Subsequent plots show the distribution of all other free parameters in the fit, along with their initial "
|
|
1006
1051
|
"values. For I_sys there is a separate fit value for each CS step."
|
|
1007
1052
|
description += self._compute_bin_description(
|
|
1008
|
-
total_bins=data["total_bins"],
|
|
1053
|
+
total_bins=data["total_bins"],
|
|
1054
|
+
bin_strs=data["bin_strs"],
|
|
1055
|
+
sampled_bins=data["sampled_bins"],
|
|
1009
1056
|
)
|
|
1010
1057
|
|
|
1011
1058
|
metric = ReportMetric(
|
|
@@ -1019,7 +1066,13 @@ class _PolcalQualityMixin:
|
|
|
1019
1066
|
return metric.model_dump()
|
|
1020
1067
|
|
|
1021
1068
|
def _store_polcal_fit_resdiuals(
|
|
1022
|
-
self,
|
|
1069
|
+
self,
|
|
1070
|
+
*,
|
|
1071
|
+
polcal_fitter: PolcalFitter,
|
|
1072
|
+
label: str,
|
|
1073
|
+
bin_nums: list[int],
|
|
1074
|
+
bin_labels: list[str],
|
|
1075
|
+
thinning_stride: int | None,
|
|
1023
1076
|
):
|
|
1024
1077
|
"""Store flux residuals and chisq values for a local fit."""
|
|
1025
1078
|
fit_container = polcal_fitter.local_objects
|
|
@@ -1029,7 +1082,7 @@ class _PolcalQualityMixin:
|
|
|
1029
1082
|
num_points = np.prod(fov_shape)
|
|
1030
1083
|
residual_array = np.zeros((num_mod, num_steps, num_points))
|
|
1031
1084
|
red_chi_list = []
|
|
1032
|
-
for i in range(num_points):
|
|
1085
|
+
for i in range(num_points)[::thinning_stride]:
|
|
1033
1086
|
## Fit residuals
|
|
1034
1087
|
point_TM = copy.deepcopy(fit_container.telescope)
|
|
1035
1088
|
point_CM = copy.deepcopy(fit_container.calibration_unit)
|
|
@@ -1054,7 +1107,8 @@ class _PolcalQualityMixin:
|
|
|
1054
1107
|
chisq = np.sum(flat_residual**2)
|
|
1055
1108
|
num_free = sum([fit_params[p].vary for p in fit_params])
|
|
1056
1109
|
red_chisq = chisq / num_free
|
|
1057
|
-
|
|
1110
|
+
if not np.isnan(red_chisq):
|
|
1111
|
+
red_chi_list.append(red_chisq)
|
|
1058
1112
|
|
|
1059
1113
|
# Convert residuals to panda DataFrame, which will greatly simplify plotting
|
|
1060
1114
|
col_list = sum(
|
|
@@ -1076,6 +1130,7 @@ class _PolcalQualityMixin:
|
|
|
1076
1130
|
f"{num_bins} {bin_label}" for num_bins, bin_label in zip(bin_nums, bin_labels)
|
|
1077
1131
|
],
|
|
1078
1132
|
"total_bins": int(np.prod(bin_nums)),
|
|
1133
|
+
"sampled_bins": len(red_chi_list),
|
|
1079
1134
|
"residual_json": dataframe_str,
|
|
1080
1135
|
"red_chi_list": red_chi_list,
|
|
1081
1136
|
}
|
|
@@ -1113,10 +1168,11 @@ class _PolcalQualityMixin:
|
|
|
1113
1168
|
dataframe_json=data["residual_json"],
|
|
1114
1169
|
)
|
|
1115
1170
|
|
|
1116
|
-
description = "The top plot shows relative flux residual distributions for all polcal Calibration Sequence "
|
|
1117
|
-
"steps. The bottom plot shows the reduced chi-squared distribution of all fits."
|
|
1171
|
+
description = "The top plot shows relative flux residual distributions for all polcal Calibration Sequence steps. The bottom plot shows the reduced chi-squared distribution of all fits."
|
|
1118
1172
|
description += self._compute_bin_description(
|
|
1119
|
-
total_bins=data["total_bins"],
|
|
1173
|
+
total_bins=data["total_bins"],
|
|
1174
|
+
bin_strs=data["bin_strs"],
|
|
1175
|
+
sampled_bins=data["sampled_bins"],
|
|
1120
1176
|
)
|
|
1121
1177
|
|
|
1122
1178
|
metric = ReportMetric(
|
|
@@ -1136,15 +1192,19 @@ class _PolcalQualityMixin:
|
|
|
1136
1192
|
label: str,
|
|
1137
1193
|
bin_nums: list[int],
|
|
1138
1194
|
bin_labels: list[str],
|
|
1195
|
+
thinning_stride: int | None,
|
|
1139
1196
|
):
|
|
1140
1197
|
"""Compute modulation efficiency for all fit bins and store in a file."""
|
|
1141
1198
|
fov_shape = polcal_fitter.local_objects.dresser.shape
|
|
1142
1199
|
num_mod = polcal_fitter.local_objects.dresser.nummod
|
|
1143
1200
|
num_points = np.prod(fov_shape)
|
|
1144
1201
|
flat_demod = np.reshape(polcal_fitter.demodulation_matrices, (num_points, 4, num_mod))
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1202
|
+
thinned_demod = flat_demod[::thinning_stride, :, :]
|
|
1203
|
+
# This will have shape (num_points, 4)
|
|
1204
|
+
flat_efficiency = 1.0 / np.sqrt(num_mod * np.sum(thinned_demod**2, axis=2))
|
|
1205
|
+
|
|
1206
|
+
nan_idx = np.sum(np.isnan(flat_efficiency), axis=1).astype(bool)
|
|
1207
|
+
flat_efficiency = flat_efficiency[~nan_idx, :]
|
|
1148
1208
|
|
|
1149
1209
|
# Because ndarrays are not JSON-able
|
|
1150
1210
|
# Also, transpose it so the Stokes parameters are the first dimension
|
|
@@ -1165,6 +1225,7 @@ class _PolcalQualityMixin:
|
|
|
1165
1225
|
f"{num_bins} {bin_label}" for num_bins, bin_label in zip(bin_nums, bin_labels)
|
|
1166
1226
|
],
|
|
1167
1227
|
"total_bins": int(np.prod(bin_nums)),
|
|
1228
|
+
"sampled_bins": flat_efficiency.shape[0],
|
|
1168
1229
|
"efficiency_list": efficiency_list,
|
|
1169
1230
|
"warnings": warnings,
|
|
1170
1231
|
}
|
|
@@ -1183,7 +1244,9 @@ class _PolcalQualityMixin:
|
|
|
1183
1244
|
|
|
1184
1245
|
description = "The modulation efficiencies for all fit modulation matrices."
|
|
1185
1246
|
description += self._compute_bin_description(
|
|
1186
|
-
total_bins=data["total_bins"],
|
|
1247
|
+
total_bins=data["total_bins"],
|
|
1248
|
+
bin_strs=data["bin_strs"],
|
|
1249
|
+
sampled_bins=data["sampled_bins"],
|
|
1187
1250
|
)
|
|
1188
1251
|
|
|
1189
1252
|
metric = ReportMetric(
|
|
@@ -1197,7 +1260,9 @@ class _PolcalQualityMixin:
|
|
|
1197
1260
|
return metric.model_dump()
|
|
1198
1261
|
|
|
1199
1262
|
@staticmethod
|
|
1200
|
-
def _compute_bin_description(
|
|
1263
|
+
def _compute_bin_description(
|
|
1264
|
+
total_bins: int, bin_strs: list[str], sampled_bins: int | None = None
|
|
1265
|
+
) -> str:
|
|
1201
1266
|
"""
|
|
1202
1267
|
Construct a grammatically correct string that describes the layout of bins present in polcal data.
|
|
1203
1268
|
|
|
@@ -1210,7 +1275,11 @@ class _PolcalQualityMixin:
|
|
|
1210
1275
|
3. For greater than two bin-types we get a list with commas and a final "and":
|
|
1211
1276
|
"...spanning N TYPE1, M TYPE2, ..., and K TYPEK bins."
|
|
1212
1277
|
"""
|
|
1213
|
-
base_str = f" Data show
|
|
1278
|
+
base_str = f" Data show"
|
|
1279
|
+
if sampled_bins is not None:
|
|
1280
|
+
base_str += f" {sampled_bins} uniformly sampled points from"
|
|
1281
|
+
|
|
1282
|
+
base_str += f" {total_bins} total points spanning "
|
|
1214
1283
|
|
|
1215
1284
|
if len(bin_strs) == 1:
|
|
1216
1285
|
base_str += bin_strs[0]
|
|
@@ -46,6 +46,9 @@ class TeardownBase(WorkflowTaskBase, ABC):
|
|
|
46
46
|
with self.apm_task_step("Remove Data and Tags"):
|
|
47
47
|
self.scratch.purge()
|
|
48
48
|
|
|
49
|
+
with self.apm_task_step("Remove File Counters"):
|
|
50
|
+
self.filename_counter.purge()
|
|
51
|
+
|
|
49
52
|
with self.apm_task_step("Remove Constants"):
|
|
50
53
|
self.constants._purge()
|
|
51
54
|
|
|
@@ -3,9 +3,11 @@ Global test fixtures
|
|
|
3
3
|
"""
|
|
4
4
|
import json
|
|
5
5
|
from collections import defaultdict
|
|
6
|
+
from copy import deepcopy
|
|
6
7
|
from datetime import datetime
|
|
7
8
|
from datetime import timedelta
|
|
8
9
|
from pathlib import Path
|
|
10
|
+
from random import choice
|
|
9
11
|
from random import randint
|
|
10
12
|
from random import random
|
|
11
13
|
from typing import Any
|
|
@@ -510,7 +512,12 @@ class InstAccess(L0FitsAccess):
|
|
|
510
512
|
|
|
511
513
|
|
|
512
514
|
@pytest.fixture(scope="session")
|
|
513
|
-
def
|
|
515
|
+
def cs_data_shape():
|
|
516
|
+
return (10, 4, 3)
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
@pytest.fixture(scope="session")
|
|
520
|
+
def cs_with_correct_geometry(cs_data_shape):
|
|
514
521
|
dark_status = [
|
|
515
522
|
"DarkShutter",
|
|
516
523
|
"FieldStop (5arcmin)",
|
|
@@ -561,7 +568,6 @@ def cs_with_correct_geometry():
|
|
|
561
568
|
"clear",
|
|
562
569
|
"clear",
|
|
563
570
|
]
|
|
564
|
-
data_shape = (1, 1, 1)
|
|
565
571
|
num_steps = len(pol_theta)
|
|
566
572
|
out_dict = dict()
|
|
567
573
|
start_time = datetime.fromisoformat("2022-05-25T12:00:00")
|
|
@@ -587,14 +593,14 @@ def cs_with_correct_geometry():
|
|
|
587
593
|
for m in range(ds.num_mod):
|
|
588
594
|
hdu_list.append(
|
|
589
595
|
fits.PrimaryHDU(
|
|
590
|
-
data=np.ones(
|
|
596
|
+
data=np.ones(cs_data_shape) * 1e3, header=fits.Header(header_list.pop(0))
|
|
591
597
|
)
|
|
592
598
|
)
|
|
593
599
|
|
|
594
600
|
out_dict[n] = [InstAccess(h) for h in hdu_list]
|
|
595
601
|
start_time = ds.start_time + timedelta(seconds=60)
|
|
596
602
|
|
|
597
|
-
return out_dict
|
|
603
|
+
return out_dict
|
|
598
604
|
|
|
599
605
|
|
|
600
606
|
@pytest.fixture(
|
|
@@ -630,11 +636,11 @@ def visp_modulation_matrix() -> np.ndarray:
|
|
|
630
636
|
|
|
631
637
|
|
|
632
638
|
@pytest.fixture(scope="session")
|
|
633
|
-
def
|
|
639
|
+
def fully_realistic_local_cs(
|
|
634
640
|
cs_with_correct_geometry, visp_modulation_matrix, pac_fit_mode, pac_init_set
|
|
635
641
|
):
|
|
636
642
|
|
|
637
|
-
cs_dict
|
|
643
|
+
cs_dict = cs_with_correct_geometry
|
|
638
644
|
dresser = Dresser()
|
|
639
645
|
dresser.add_drawer(Drawer(cs_dict, skip_darks=False))
|
|
640
646
|
CM = CalibrationUnit(dresser)
|
|
@@ -663,21 +669,75 @@ def fully_realistic_cs(
|
|
|
663
669
|
|
|
664
670
|
|
|
665
671
|
@pytest.fixture(scope="session")
|
|
666
|
-
def
|
|
672
|
+
def fully_realistic_local_dresser(fully_realistic_local_cs):
|
|
667
673
|
dresser = Dresser()
|
|
668
|
-
dresser.add_drawer(Drawer(
|
|
674
|
+
dresser.add_drawer(Drawer(fully_realistic_local_cs))
|
|
675
|
+
return dresser
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
@pytest.fixture(scope="session")
|
|
679
|
+
def fully_realistic_global_dresser(fully_realistic_local_cs):
|
|
680
|
+
|
|
681
|
+
global_cs_dict = defaultdict(list)
|
|
682
|
+
for step, step_list in fully_realistic_local_cs.items():
|
|
683
|
+
for hdu in step_list:
|
|
684
|
+
hdu_copy = deepcopy(hdu)
|
|
685
|
+
hdu_copy.data = hdu_copy.data[0, 0, 0][None, None, None]
|
|
686
|
+
global_cs_dict[step].append(hdu_copy)
|
|
687
|
+
|
|
688
|
+
dresser = Dresser()
|
|
689
|
+
dresser.add_drawer(Drawer(global_cs_dict, remove_I_trend=False))
|
|
690
|
+
|
|
669
691
|
return dresser
|
|
670
692
|
|
|
671
693
|
|
|
672
694
|
@pytest.fixture(scope="session")
|
|
673
|
-
def
|
|
674
|
-
return
|
|
675
|
-
|
|
676
|
-
|
|
695
|
+
def num_polcal_metrics_sample_points() -> int:
|
|
696
|
+
return 10
|
|
697
|
+
|
|
698
|
+
|
|
699
|
+
@pytest.fixture(scope="session")
|
|
700
|
+
def polcal_fit_nan_locations(cs_data_shape, num_polcal_metrics_sample_points):
|
|
701
|
+
# We want one nan that will be un-thinned so it can be ignored by downstream checks
|
|
702
|
+
# and one nan that will be thinned so we can confirm the interaction between thinning and
|
|
703
|
+
# downstream filtering
|
|
704
|
+
num_total_points = np.prod(cs_data_shape)
|
|
705
|
+
remainder = num_total_points % num_polcal_metrics_sample_points
|
|
706
|
+
if remainder:
|
|
707
|
+
stride = num_total_points // (num_polcal_metrics_sample_points - 1)
|
|
708
|
+
else:
|
|
709
|
+
stride = num_total_points // num_polcal_metrics_sample_points
|
|
710
|
+
|
|
711
|
+
thinned_index = list(range(num_total_points))[::stride]
|
|
712
|
+
discarded_indices = list(set(range(num_total_points)) - set(thinned_index))
|
|
713
|
+
|
|
714
|
+
included_nan_idx = np.unravel_index(choice(thinned_index), cs_data_shape)
|
|
715
|
+
discarded_nan_idx = np.unravel_index(choice(discarded_indices), cs_data_shape)
|
|
716
|
+
|
|
717
|
+
return [included_nan_idx, discarded_nan_idx]
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
@pytest.fixture(scope="session")
|
|
721
|
+
def post_fit_polcal_fitter(
|
|
722
|
+
fully_realistic_local_dresser,
|
|
723
|
+
fully_realistic_global_dresser,
|
|
724
|
+
pac_init_set,
|
|
725
|
+
pac_fit_mode,
|
|
726
|
+
polcal_fit_nan_locations,
|
|
727
|
+
) -> PolcalFitter:
|
|
728
|
+
fitter = PolcalFitter(
|
|
729
|
+
local_dresser=fully_realistic_local_dresser,
|
|
730
|
+
global_dresser=fully_realistic_global_dresser,
|
|
677
731
|
fit_mode=pac_fit_mode,
|
|
678
732
|
init_set=pac_init_set,
|
|
679
733
|
fit_TM=False,
|
|
734
|
+
suppress_local_starting_values=True,
|
|
680
735
|
)
|
|
736
|
+
for idx in polcal_fit_nan_locations:
|
|
737
|
+
for parameter in fitter.fit_parameters[idx].values():
|
|
738
|
+
parameter.set(value=np.nan)
|
|
739
|
+
|
|
740
|
+
return fitter
|
|
681
741
|
|
|
682
742
|
|
|
683
743
|
class InputDatasetTask(WorkflowTaskBase, InputDatasetMixin):
|
|
@@ -186,6 +186,7 @@ def quality_metrics(dataframe_json) -> list[Metric]:
|
|
|
186
186
|
},
|
|
187
187
|
"bin_strs": ["bin1", "bin2"],
|
|
188
188
|
"total_bins": 100,
|
|
189
|
+
"sampled_bins": 20,
|
|
189
190
|
"num_varied_I_sys": 2,
|
|
190
191
|
},
|
|
191
192
|
["QUALITY_POLCAL_LOCAL_PAR_VALS", "QUALITY_TASK_BEAM 1"],
|
|
@@ -194,6 +195,7 @@ def quality_metrics(dataframe_json) -> list[Metric]:
|
|
|
194
195
|
{
|
|
195
196
|
"bin_strs": ["bin1", "bin2"],
|
|
196
197
|
"total_bins": 100,
|
|
198
|
+
"sampled_bins": 20,
|
|
197
199
|
"red_chi_list": [1, 2, 3],
|
|
198
200
|
"residual_json": dataframe_json,
|
|
199
201
|
},
|
|
@@ -203,6 +205,7 @@ def quality_metrics(dataframe_json) -> list[Metric]:
|
|
|
203
205
|
{
|
|
204
206
|
"bin_strs": ["bin1", "bin2"],
|
|
205
207
|
"total_bins": 100,
|
|
208
|
+
"sampled_bins": 20,
|
|
206
209
|
"efficiency_list": ((np.random.randn(4, 100) - 0.5) * 0.3).tolist(),
|
|
207
210
|
"warnings": ["A warning"],
|
|
208
211
|
},
|