dkist-processing-common 13.0.4__tar.gz → 13.0.5__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-13.0.4 → dkist_processing_common-13.0.5}/CHANGELOG.rst +9 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/PKG-INFO +1 -1
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/metric_code.py +0 -4
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/quality/_base.py +0 -80
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/quality/_metrics.py +0 -212
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_assemble_quality.py +4 -58
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_quality_mixin.py +0 -219
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common.egg-info/PKG-INFO +1 -1
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/.gitignore +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/.pre-commit-config.yaml +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/.readthedocs.yml +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/.snyk +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/README.rst +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/bitbucket-pipelines.yml +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/changelog/.gitempty +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/_util/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/_util/constants.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/_util/graphql.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/_util/scratch.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/_util/tags.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/array.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/asdf.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/basemodel.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/bytes.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/fits.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/iobase.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/json.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/path.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/quality.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/codecs/str.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/config.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/fonts/Lato-Regular.ttf +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/fonts/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/manual.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/constants.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/dkist_location.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/extras.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/fits_access.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/flower_pot.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/fried_parameter.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/graphql.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/input_dataset.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/message.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/message_queue_binding.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/parameters.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/quality.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/tags.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/task_name.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/telemetry.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/models/wavelength.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/average_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/cs_step.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/dsps_repeat.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/experiment_id_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/id_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/l0_fits_access.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/l1_fits_access.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/lookup_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/near_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/observing_program_id_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/proposal_id_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/quality.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/retarder.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/single_value_single_key_flower.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/task.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/time.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/unique_bud.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/parsers/wavelength.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/assemble_movie.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/base.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/l1_output_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/globus.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/interservice_bus.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/metadata_store.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/object_store.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/mixin/quality/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/output_data_base.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/parse_l0_input_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/quality_metrics.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/teardown.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/transfer_input_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/trial_catalog.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/trial_output_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/write_extra.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/write_l1.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tasks/write_l1_base.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/__init__.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/conftest.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/mock_metadata_store.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_assemble_movie.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_base.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_codecs.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_constants.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_construct_dataset_extras.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_cs_step.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_dkist_location.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_fits_access.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_flower_pot.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_fried_parameter.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_input_dataset.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_interservice_bus.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_interservice_bus_mixin.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_manual_processing.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_output_data_base.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_parameters.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_parse_l0_input_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_publish_catalog_messages.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_quality.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_scratch.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_stems.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_submit_dataset_metadata.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_tags.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_task_name.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_task_parsing.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_teardown.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_transfer_input_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_transfer_l1_output_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_trial_catalog.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_trial_output_data.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_workflow_task_base.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common/tests/test_write_l1.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common.egg-info/SOURCES.txt +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common.egg-info/dependency_links.txt +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common.egg-info/requires.txt +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/dkist_processing_common.egg-info/top_level.txt +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/Makefile +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/changelog.rst +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/conf.py +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/index.rst +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/landing_page.rst +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/make.bat +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/docs/requirements.txt +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/licenses/LICENSE.rst +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/pyproject.toml +0 -0
- {dkist_processing_common-13.0.4 → dkist_processing_common-13.0.5}/setup.cfg +0 -0
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
v13.0.5 (2026-04-20)
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
Features
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
- Remove 4 unused quality metric codes: RANGE, NOISE, SENSITIVITY, HISTORICAL. (`#329 <https://bitbucket.org/dkistdc/dkist-processing-common/pull-requests/329>`__)
|
|
8
|
+
|
|
9
|
+
|
|
1
10
|
v13.0.4 (2026-04-16)
|
|
2
11
|
====================
|
|
3
12
|
|
|
@@ -13,15 +13,11 @@ class MetricCode(StrEnum):
|
|
|
13
13
|
frame_rms = "FRAME_RMS"
|
|
14
14
|
fried_parameter = "FRIED_PARAMETER"
|
|
15
15
|
health_status = "HEALTH_STATUS"
|
|
16
|
-
historical = "HISTORICAL"
|
|
17
16
|
light_level = "LIGHT_LEVEL"
|
|
18
|
-
noise = "NOISE"
|
|
19
17
|
polcal_constant_par_vals = "POLCAL_CONSTANT_PAR_VALS"
|
|
20
18
|
polcal_efficiency = "POLCAL_EFFICIENCY"
|
|
21
19
|
polcal_fit_residuals = "POLCAL_FIT_RESIDUALS"
|
|
22
20
|
polcal_global_par_vals = "POLCAL_GLOBAL_PAR_VALS"
|
|
23
21
|
polcal_local_par_vals = "POLCAL_LOCAL_PAR_VALS"
|
|
24
|
-
range = "RANGE"
|
|
25
|
-
sensitivity = "SENSITIVITY"
|
|
26
22
|
task_types = "TASK_TYPES"
|
|
27
23
|
wavecal_fit = "WAVECAL_FIT"
|
|
@@ -10,13 +10,11 @@ from dkist_processing_common.models.tags import Tag
|
|
|
10
10
|
from dkist_processing_common.models.task_name import TaskName
|
|
11
11
|
from dkist_processing_common.tasks.mixin.quality._metrics import _PolcalQualityMixin
|
|
12
12
|
from dkist_processing_common.tasks.mixin.quality._metrics import _SimplePlotQualityMixin
|
|
13
|
-
from dkist_processing_common.tasks.mixin.quality._metrics import _SimpleQualityMixin
|
|
14
13
|
from dkist_processing_common.tasks.mixin.quality._metrics import _TableQualityMixin
|
|
15
14
|
from dkist_processing_common.tasks.mixin.quality._metrics import _WavecalQualityMixin
|
|
16
15
|
|
|
17
16
|
|
|
18
17
|
class QualityMixin(
|
|
19
|
-
_SimpleQualityMixin,
|
|
20
18
|
_SimplePlotQualityMixin,
|
|
21
19
|
_TableQualityMixin,
|
|
22
20
|
_PolcalQualityMixin,
|
|
@@ -66,11 +64,7 @@ class QualityMixin(
|
|
|
66
64
|
def quality_metrics_no_task_dependence(self) -> dict:
|
|
67
65
|
"""Return a dict of the quality metrics with no task dependence."""
|
|
68
66
|
return {
|
|
69
|
-
"NOISE": self.quality_build_noise,
|
|
70
|
-
"SENSITIVITY": self.quality_build_sensitivity,
|
|
71
67
|
"TASK_TYPES": self.quality_build_task_type_counts,
|
|
72
|
-
"HISTORICAL": self.quality_build_historical,
|
|
73
|
-
"RANGE": self.quality_build_range,
|
|
74
68
|
"WAVECAL_FIT": self.quality_build_wavecal_results,
|
|
75
69
|
}
|
|
76
70
|
|
|
@@ -106,77 +100,3 @@ class QualityMixin(
|
|
|
106
100
|
self.write(
|
|
107
101
|
data=values, tags=tags, encoder=json_encoder, allow_nan=False, cls=QualityValueEncoder
|
|
108
102
|
)
|
|
109
|
-
|
|
110
|
-
@staticmethod
|
|
111
|
-
def avg_noise(data) -> float:
|
|
112
|
-
"""Estimate the average noise in the image."""
|
|
113
|
-
if len(data.shape) == 2: # 2D data
|
|
114
|
-
corner_square_length = int(data.shape[0] * 0.2) # 1/5th of x dimension of array
|
|
115
|
-
corner_square_height = int(data.shape[1] * 0.2) # 1/5th of y dimension of array
|
|
116
|
-
|
|
117
|
-
square_1 = data[0:corner_square_length, 0:corner_square_height] # top left
|
|
118
|
-
|
|
119
|
-
square_2 = data[-corner_square_length:, 0:corner_square_height] # top right
|
|
120
|
-
|
|
121
|
-
square_3 = data[0:corner_square_length, -corner_square_height:] # bottom left
|
|
122
|
-
|
|
123
|
-
square_4 = data[-corner_square_length:, -corner_square_height:] # bottom right
|
|
124
|
-
|
|
125
|
-
return np.nanmean(
|
|
126
|
-
[
|
|
127
|
-
np.nanstd(square_1),
|
|
128
|
-
np.nanstd(square_2),
|
|
129
|
-
np.nanstd(square_3),
|
|
130
|
-
np.nanstd(square_4),
|
|
131
|
-
]
|
|
132
|
-
)
|
|
133
|
-
|
|
134
|
-
if len(data.shape) == 3: # 3D data
|
|
135
|
-
corner_cube_length = int(data.shape[0] * 0.2) # 1/5th of x dimension of array
|
|
136
|
-
corner_cube_height = int(data.shape[1] * 0.2) # 1/5th of y dimension of array
|
|
137
|
-
corner_cube_width = int(data.shape[2] * 0.2) # 1/5th of z dimension of array
|
|
138
|
-
|
|
139
|
-
cube_1 = data[
|
|
140
|
-
0:corner_cube_length, 0:corner_cube_height, 0:corner_cube_width
|
|
141
|
-
] # top left front
|
|
142
|
-
|
|
143
|
-
cube_2 = data[
|
|
144
|
-
0:corner_cube_length, 0:corner_cube_height, -corner_cube_width:
|
|
145
|
-
] # top left back
|
|
146
|
-
|
|
147
|
-
cube_3 = data[
|
|
148
|
-
-corner_cube_length:, 0:corner_cube_height, 0:corner_cube_width
|
|
149
|
-
] # top right front
|
|
150
|
-
|
|
151
|
-
cube_4 = data[
|
|
152
|
-
-corner_cube_length:, 0:corner_cube_height, -corner_cube_width:
|
|
153
|
-
] # top right back
|
|
154
|
-
|
|
155
|
-
cube_5 = data[
|
|
156
|
-
0:corner_cube_length, -corner_cube_height:, 0:corner_cube_width
|
|
157
|
-
] # bottom left front
|
|
158
|
-
|
|
159
|
-
cube_6 = data[
|
|
160
|
-
0:corner_cube_length, -corner_cube_height:, -corner_cube_width:
|
|
161
|
-
] # bottom left back
|
|
162
|
-
|
|
163
|
-
cube_7 = data[
|
|
164
|
-
-corner_cube_length:, -corner_cube_height:, 0:corner_cube_width
|
|
165
|
-
] # bottom right front
|
|
166
|
-
|
|
167
|
-
cube_8 = data[
|
|
168
|
-
-corner_cube_length:, -corner_cube_height:, -corner_cube_width:
|
|
169
|
-
] # bottom right back
|
|
170
|
-
|
|
171
|
-
return np.nanmean(
|
|
172
|
-
[
|
|
173
|
-
np.nanstd(cube_1),
|
|
174
|
-
np.nanstd(cube_2),
|
|
175
|
-
np.nanstd(cube_3),
|
|
176
|
-
np.nanstd(cube_4),
|
|
177
|
-
np.nanstd(cube_5),
|
|
178
|
-
np.nanstd(cube_6),
|
|
179
|
-
np.nanstd(cube_7),
|
|
180
|
-
np.nanstd(cube_8),
|
|
181
|
-
]
|
|
182
|
-
)
|
|
@@ -39,133 +39,9 @@ from dkist_processing_common.models.tags import Tag
|
|
|
39
39
|
logger = logging.getLogger(__name__)
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
class _SimpleQualityMixin:
|
|
43
|
-
|
|
44
|
-
def quality_store_range(self, name: str, warnings: list[str]):
|
|
45
|
-
"""
|
|
46
|
-
Insert range checking warnings into the schema used to record quality info.
|
|
47
|
-
|
|
48
|
-
Parameters
|
|
49
|
-
----------
|
|
50
|
-
name: name of the parameter / measurement for which range was out of bounds
|
|
51
|
-
warnings: list of warnings to be entered into the quality report
|
|
52
|
-
"""
|
|
53
|
-
data = {"name": name, "warnings": warnings}
|
|
54
|
-
self._record_values(values=data, tags=Tag.quality(MetricCode.range))
|
|
55
|
-
|
|
56
|
-
def quality_build_range(self) -> dict:
|
|
57
|
-
"""Build range data schema from stored data."""
|
|
58
|
-
warnings = []
|
|
59
|
-
# Loop over files that contain data for this metric
|
|
60
|
-
for path in self.read(tags=Tag.quality(MetricCode.range)):
|
|
61
|
-
with path.open() as f:
|
|
62
|
-
data = json.load(f)
|
|
63
|
-
for warning in data["warnings"]:
|
|
64
|
-
warnings.append(warning)
|
|
65
|
-
|
|
66
|
-
return ReportMetric(
|
|
67
|
-
name="Range checks",
|
|
68
|
-
description="This metric is checking that certain input and calculated parameters "
|
|
69
|
-
"fall within a valid data range. If no parameters are listed here, all "
|
|
70
|
-
"pipeline parameters were measured to be in range",
|
|
71
|
-
metric_code=MetricCode.range,
|
|
72
|
-
warnings=self._format_warnings(warnings),
|
|
73
|
-
).model_dump()
|
|
74
|
-
|
|
75
|
-
|
|
76
42
|
class _SimplePlotQualityMixin:
|
|
77
43
|
"""Mixin containing metrics that present as simple x/y plots."""
|
|
78
44
|
|
|
79
|
-
@staticmethod
|
|
80
|
-
def _create_2d_plot_with_datetime_metric(
|
|
81
|
-
name: str,
|
|
82
|
-
description: str,
|
|
83
|
-
metric_code: str,
|
|
84
|
-
xlabel: str,
|
|
85
|
-
ylabel: str,
|
|
86
|
-
series_data: dict[str, list[list[Any]]],
|
|
87
|
-
series_name: str | None = None,
|
|
88
|
-
ylabel_horizontal: bool = False,
|
|
89
|
-
ylim: tuple[float, float] | None = None,
|
|
90
|
-
statement: str | None = None,
|
|
91
|
-
warnings: list[str] | None = None,
|
|
92
|
-
facet: str | None = None,
|
|
93
|
-
) -> dict:
|
|
94
|
-
for k, v in series_data.items():
|
|
95
|
-
# Convert datetime strings to datetime objects
|
|
96
|
-
series_data[k][0] = [datetime.fromisoformat(i) for i in v[0]]
|
|
97
|
-
# Sort the lists to make sure they are in ascending time order
|
|
98
|
-
series_data[k][0], series_data[k][1] = (list(t) for t in zip(*sorted(zip(v[0], v[1]))))
|
|
99
|
-
plot_data = Plot2D(
|
|
100
|
-
series_data=series_data,
|
|
101
|
-
xlabel=xlabel,
|
|
102
|
-
ylabel=ylabel,
|
|
103
|
-
series_name=series_name,
|
|
104
|
-
ylabel_horizontal=ylabel_horizontal,
|
|
105
|
-
ylim=ylim,
|
|
106
|
-
)
|
|
107
|
-
metric = ReportMetric(
|
|
108
|
-
name=name,
|
|
109
|
-
description=description,
|
|
110
|
-
metric_code=metric_code,
|
|
111
|
-
facet=facet,
|
|
112
|
-
statement=statement,
|
|
113
|
-
plot_data=plot_data,
|
|
114
|
-
warnings=warnings,
|
|
115
|
-
)
|
|
116
|
-
return metric.model_dump()
|
|
117
|
-
|
|
118
|
-
def _record_2d_plot_values(
|
|
119
|
-
self,
|
|
120
|
-
x_values: list[str],
|
|
121
|
-
y_values: list[float],
|
|
122
|
-
tags: Iterable[str] | str,
|
|
123
|
-
series_name: str = "",
|
|
124
|
-
task_type: str | None = None,
|
|
125
|
-
):
|
|
126
|
-
"""
|
|
127
|
-
Encode values for a 2d plot type metric and store as a file.
|
|
128
|
-
|
|
129
|
-
Parameters
|
|
130
|
-
----------
|
|
131
|
-
x_values: values to apply to the x axis of a 2d plot
|
|
132
|
-
y_values: values to apply to the y axis of a 2d plot
|
|
133
|
-
tags: list of tags relating to the specific quality parameter being stored
|
|
134
|
-
series_name: name of the series if this is part of a multi series plot metric
|
|
135
|
-
task_type: type of data to be used - dark, gain, etc
|
|
136
|
-
"""
|
|
137
|
-
if isinstance(tags, str):
|
|
138
|
-
tags = [tags]
|
|
139
|
-
axis_are_different_lengths = len(x_values) != len(y_values)
|
|
140
|
-
axis_are_zero_length = not x_values or not y_values
|
|
141
|
-
if axis_are_different_lengths or axis_are_zero_length:
|
|
142
|
-
raise ValueError(
|
|
143
|
-
f"Cannot store 2D plot values with 0 length or different length axis. "
|
|
144
|
-
f"{len(x_values)=}, {len(y_values)=}"
|
|
145
|
-
)
|
|
146
|
-
data = {"x_values": x_values, "y_values": y_values, "series_name": series_name}
|
|
147
|
-
if task_type:
|
|
148
|
-
tags.append(Tag.quality_task(quality_task_type=task_type))
|
|
149
|
-
self._record_values(values=data, tags=tags)
|
|
150
|
-
|
|
151
|
-
def _load_2d_plot_values(self, tags: str | list[str], task_type: str | None = None):
|
|
152
|
-
"""Load all quality files for a given tag and return the merged datetimes and values."""
|
|
153
|
-
if isinstance(tags, str):
|
|
154
|
-
tags = [tags]
|
|
155
|
-
if task_type:
|
|
156
|
-
tags.append(Tag.quality_task(quality_task_type=task_type))
|
|
157
|
-
all_plot_data = defaultdict(list)
|
|
158
|
-
for path in self.read(tags=tags):
|
|
159
|
-
with path.open() as f:
|
|
160
|
-
data = json.load(f)
|
|
161
|
-
series_name = str(data["series_name"])
|
|
162
|
-
if series_name in all_plot_data.keys():
|
|
163
|
-
all_plot_data[series_name][0].extend(data["x_values"])
|
|
164
|
-
all_plot_data[series_name][1].extend(data["y_values"])
|
|
165
|
-
else:
|
|
166
|
-
all_plot_data[series_name] = [data["x_values"], data["y_values"]]
|
|
167
|
-
return all_plot_data
|
|
168
|
-
|
|
169
45
|
@staticmethod
|
|
170
46
|
def _find_iqr_outliers(datetimes: Sequence[datetime], values: Sequence[float]) -> list[str]:
|
|
171
47
|
"""
|
|
@@ -190,57 +66,6 @@ class _SimplePlotQualityMixin:
|
|
|
190
66
|
)
|
|
191
67
|
return warnings
|
|
192
68
|
|
|
193
|
-
def quality_store_noise(self, datetimes: list[str], values: list[float], stokes: str = "I"):
|
|
194
|
-
"""Collect and store datetime / value pairs for the noise data."""
|
|
195
|
-
self._record_2d_plot_values(
|
|
196
|
-
x_values=datetimes,
|
|
197
|
-
y_values=values,
|
|
198
|
-
series_name=stokes,
|
|
199
|
-
tags=[Tag.quality(MetricCode.noise), Tag.stokes(stokes)],
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
def quality_build_noise(self) -> dict:
|
|
203
|
-
"""Build noise schema from stored data."""
|
|
204
|
-
series_data = self._load_2d_plot_values(tags=[Tag.quality(MetricCode.noise)])
|
|
205
|
-
return self._create_2d_plot_with_datetime_metric(
|
|
206
|
-
name=f"Noise Estimation",
|
|
207
|
-
description="Estimate of the noise in L1 frames. Noise is computed as the average of the stddev of "
|
|
208
|
-
"boxes/cubes that extend 1/5 from the edge of the images on all sides. "
|
|
209
|
-
"One measurement taken per L1 frame.",
|
|
210
|
-
metric_code=MetricCode.noise,
|
|
211
|
-
xlabel="Time",
|
|
212
|
-
ylabel="Noise (adu)",
|
|
213
|
-
series_data=series_data,
|
|
214
|
-
warnings=None,
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
def quality_store_sensitivity(
|
|
218
|
-
self, stokes: Literal["I", "Q", "U", "V"], datetimes: list[str], values: list[float]
|
|
219
|
-
):
|
|
220
|
-
"""Collect and store datetime / value pairs for the polarimetric noise data."""
|
|
221
|
-
self._record_2d_plot_values(
|
|
222
|
-
x_values=datetimes,
|
|
223
|
-
y_values=values,
|
|
224
|
-
series_name=stokes,
|
|
225
|
-
tags=[Tag.quality(MetricCode.sensitivity), Tag.stokes(stokes)],
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
def quality_build_sensitivity(self) -> dict:
|
|
229
|
-
"""Build polarimetric noise schema from stored data."""
|
|
230
|
-
series_data = self._load_2d_plot_values(tags=[Tag.quality(MetricCode.sensitivity)])
|
|
231
|
-
return self._create_2d_plot_with_datetime_metric(
|
|
232
|
-
name=f"Sensitivity",
|
|
233
|
-
description=f"Sensitivity is defined as the stddev of a particular Stokes parameter divided by the signal in "
|
|
234
|
-
f"Stokes I (computed as a median over the whole frame). One measurement is shown per map scan.",
|
|
235
|
-
metric_code=MetricCode.sensitivity,
|
|
236
|
-
xlabel="Time",
|
|
237
|
-
ylabel=r"$\frac{\sigma_X}{\mathrm{med}(I)}$",
|
|
238
|
-
ylabel_horizontal=True,
|
|
239
|
-
series_data=series_data,
|
|
240
|
-
series_name="Stokes Parameter",
|
|
241
|
-
warnings=None,
|
|
242
|
-
)
|
|
243
|
-
|
|
244
69
|
|
|
245
70
|
class _TableQualityMixin:
|
|
246
71
|
"""Mixing for metrics that present as tables."""
|
|
@@ -320,43 +145,6 @@ class _TableQualityMixin:
|
|
|
320
145
|
warnings=self._format_warnings(warnings),
|
|
321
146
|
)
|
|
322
147
|
|
|
323
|
-
def quality_store_historical(self, name: str, value: Any, warning: str | None = None):
|
|
324
|
-
"""
|
|
325
|
-
Insert historical data into the schema used to record quality info.
|
|
326
|
-
|
|
327
|
-
Parameters
|
|
328
|
-
----------
|
|
329
|
-
name: name of the parameter / measurement to be recorded
|
|
330
|
-
value: value of the parameter / measurement to be recorded
|
|
331
|
-
warning: warning to be entered into the quality report
|
|
332
|
-
"""
|
|
333
|
-
data = {"name": name, "value": value, "warnings": warning}
|
|
334
|
-
self._record_values(values=data, tags=Tag.quality(MetricCode.historical))
|
|
335
|
-
|
|
336
|
-
def quality_build_historical(self) -> dict:
|
|
337
|
-
"""Build historical data schema from stored data."""
|
|
338
|
-
table_data = []
|
|
339
|
-
warnings = []
|
|
340
|
-
# Loop over files that contain data for this metric
|
|
341
|
-
for path in self.read(tags=Tag.quality(MetricCode.historical)):
|
|
342
|
-
with path.open() as f:
|
|
343
|
-
data = json.load(f)
|
|
344
|
-
table_data.append([data["name"], data["value"]])
|
|
345
|
-
if data["warnings"] is not None:
|
|
346
|
-
warnings.append(data["warnings"])
|
|
347
|
-
|
|
348
|
-
# Add header row
|
|
349
|
-
table_data.insert(0, ["Metric", "Value"])
|
|
350
|
-
return self._create_table_metric(
|
|
351
|
-
name="Historical Comparisons",
|
|
352
|
-
description="Over time, the data center will be comparing some of the above quality "
|
|
353
|
-
"metrics and other parameters derived from file headers to see how the "
|
|
354
|
-
"DKIST instruments and observations are changing.",
|
|
355
|
-
metric_code=MetricCode.historical,
|
|
356
|
-
rows=table_data,
|
|
357
|
-
warnings=self._format_warnings(warnings),
|
|
358
|
-
)
|
|
359
|
-
|
|
360
148
|
|
|
361
149
|
class _PolcalQualityMixin:
|
|
362
150
|
"""Mixin Class supporting the building of polcal-specific metrics."""
|
|
@@ -76,46 +76,6 @@ def quality_metrics_old(dataframe_json) -> list[Metric]:
|
|
|
76
76
|
Quality metric data - this OLD FORMAT is being phased out
|
|
77
77
|
"""
|
|
78
78
|
metrics = [
|
|
79
|
-
Metric(
|
|
80
|
-
{
|
|
81
|
-
"x_values": ["2021-01-01T01:01:01", "2021-01-01T02:01:01"],
|
|
82
|
-
"y_values": [5, 6],
|
|
83
|
-
"series_name": "",
|
|
84
|
-
},
|
|
85
|
-
["QUALITY_NOISE"],
|
|
86
|
-
),
|
|
87
|
-
Metric(
|
|
88
|
-
{
|
|
89
|
-
"x_values": ["2021-01-01T01:01:01", "2021-01-01T02:01:01"],
|
|
90
|
-
"y_values": [1, 2],
|
|
91
|
-
"series_name": "I",
|
|
92
|
-
},
|
|
93
|
-
["QUALITY_SENSITIVITY", "STOKES_I"],
|
|
94
|
-
),
|
|
95
|
-
Metric(
|
|
96
|
-
{
|
|
97
|
-
"x_values": ["2021-01-01T01:01:01", "2021-01-01T02:01:01"],
|
|
98
|
-
"y_values": [3, 4],
|
|
99
|
-
"series_name": "Q",
|
|
100
|
-
},
|
|
101
|
-
["QUALITY_SENSITIVITY", "STOKES_Q"],
|
|
102
|
-
),
|
|
103
|
-
Metric(
|
|
104
|
-
{
|
|
105
|
-
"x_values": ["2021-01-01T01:01:01", "2021-01-01T02:01:01"],
|
|
106
|
-
"y_values": [5, 6],
|
|
107
|
-
"series_name": "U",
|
|
108
|
-
},
|
|
109
|
-
["QUALITY_SENSITIVITY", "STOKES_U"],
|
|
110
|
-
),
|
|
111
|
-
Metric(
|
|
112
|
-
{
|
|
113
|
-
"x_values": ["2021-01-01T01:01:01", "2021-01-01T02:01:01"],
|
|
114
|
-
"y_values": [7, 8],
|
|
115
|
-
"series_name": "V",
|
|
116
|
-
},
|
|
117
|
-
["QUALITY_SENSITIVITY", "STOKES_V"],
|
|
118
|
-
),
|
|
119
79
|
Metric(
|
|
120
80
|
{"task_type": "dark", "total_frames": 100, "frames_not_used": 7}, ["QUALITY_TASK_TYPES"]
|
|
121
81
|
),
|
|
@@ -170,15 +130,6 @@ def quality_metrics_old(dataframe_json) -> list[Metric]:
|
|
|
170
130
|
},
|
|
171
131
|
["QUALITY_POLCAL_EFFICIENCY", "QUALITY_TASK_BEAM 1"],
|
|
172
132
|
),
|
|
173
|
-
Metric({"name": "metric 1", "warnings": ["warning 1"]}, ["QUALITY_RANGE"]),
|
|
174
|
-
Metric({"name": "metric 2", "warnings": ["warning 2"]}, ["QUALITY_RANGE"]),
|
|
175
|
-
Metric({"name": "metric 3", "warnings": ["warning 3"]}, ["QUALITY_RANGE"]),
|
|
176
|
-
Metric({"name": "hist 1", "value": 7, "warnings": None}, ["QUALITY_HISTORICAL"]),
|
|
177
|
-
Metric({"name": "hist 2", "value": "abc", "warnings": None}, ["QUALITY_HISTORICAL"]),
|
|
178
|
-
Metric(
|
|
179
|
-
{"name": "hist 3", "value": 9.35, "warnings": "warning for historical metric 3"},
|
|
180
|
-
["QUALITY_HISTORICAL"],
|
|
181
|
-
),
|
|
182
133
|
Metric(
|
|
183
134
|
{
|
|
184
135
|
"input_wavelength_nm": [1001.0, 1002.0, 1003.0, 1004.0],
|
|
@@ -378,8 +329,6 @@ def plot_data_expected() -> Callable[[str], bool]:
|
|
|
378
329
|
"Root Mean Square (RMS) Across Frame - GAIN",
|
|
379
330
|
"Fried Parameter",
|
|
380
331
|
"Light Level",
|
|
381
|
-
"Noise Estimation",
|
|
382
|
-
"Sensitivity",
|
|
383
332
|
}
|
|
384
333
|
|
|
385
334
|
def expected(name: str) -> bool:
|
|
@@ -414,7 +363,6 @@ def table_data_expected() -> Callable[[str], bool]:
|
|
|
414
363
|
"Data Source Health",
|
|
415
364
|
"Frame Counts",
|
|
416
365
|
"PolCal Global Calibration Unit Fit - Beam 1",
|
|
417
|
-
"Historical Comparisons",
|
|
418
366
|
}
|
|
419
367
|
|
|
420
368
|
def expected(name: str) -> bool:
|
|
@@ -517,8 +465,6 @@ def warnings_expected() -> Callable[[str], bool]:
|
|
|
517
465
|
"Frame Counts",
|
|
518
466
|
"PolCal Global Calibration Unit Fit - Beam 1",
|
|
519
467
|
"PolCal Modulation Efficiency - Beam 1",
|
|
520
|
-
"Range checks",
|
|
521
|
-
"Historical Comparisons",
|
|
522
468
|
}
|
|
523
469
|
|
|
524
470
|
def expected(name: str) -> bool:
|
|
@@ -619,8 +565,8 @@ def test_assemble_quality_data(
|
|
|
619
565
|
quality_data = list(
|
|
620
566
|
chain.from_iterable(task.read(tags=Tag.quality_data(), decoder=json_decoder))
|
|
621
567
|
)
|
|
622
|
-
# With polcal, this would be
|
|
623
|
-
assert len(quality_data) ==
|
|
568
|
+
# With polcal, this would be 16, but the polcal metrics are not included with this task
|
|
569
|
+
assert len(quality_data) == 12
|
|
624
570
|
for metric_data in quality_data:
|
|
625
571
|
rm: ReportMetric = ReportMetric.from_dict(metric_data)
|
|
626
572
|
assert isinstance(rm.name, str)
|
|
@@ -671,8 +617,8 @@ def test_assemble_quality_data_for_polcal(
|
|
|
671
617
|
quality_data = list(
|
|
672
618
|
chain.from_iterable(task.read(tags=Tag.quality_data(), decoder=json_decoder))
|
|
673
619
|
)
|
|
674
|
-
# this is
|
|
675
|
-
assert len(quality_data) ==
|
|
620
|
+
# this is 16 with polcal
|
|
621
|
+
assert len(quality_data) == 16
|
|
676
622
|
for metric_data in quality_data:
|
|
677
623
|
rm: ReportMetric = ReportMetric.from_dict(metric_data)
|
|
678
624
|
assert isinstance(rm.name, str)
|