dkist-processing-common 12.10.0__tar.gz → 13.0.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-12.10.0 → dkist_processing_common-13.0.0}/CHANGELOG.rst +17 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/PKG-INFO +1 -1
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/task.py +1 -1
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/time.py +103 -50
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_stems.py +118 -9
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common.egg-info/PKG-INFO +1 -1
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/.gitignore +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/.pre-commit-config.yaml +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/.readthedocs.yml +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/.snyk +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/README.rst +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/bitbucket-pipelines.yml +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/changelog/.gitempty +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/_util/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/_util/constants.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/_util/graphql.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/_util/scratch.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/_util/tags.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/array.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/asdf.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/basemodel.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/bytes.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/fits.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/iobase.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/json.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/path.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/quality.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/codecs/str.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/config.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/fonts/Lato-Regular.ttf +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/fonts/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/manual.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/constants.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/dkist_location.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/extras.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/fits_access.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/flower_pot.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/fried_parameter.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/graphql.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/input_dataset.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/message.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/message_queue_binding.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/metric_code.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/parameters.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/quality.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/tags.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/task_name.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/telemetry.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/models/wavelength.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/average_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/cs_step.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/dsps_repeat.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/experiment_id_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/id_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/l0_fits_access.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/l1_fits_access.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/lookup_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/near_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/observing_program_id_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/proposal_id_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/quality.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/retarder.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/single_value_single_key_flower.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/unique_bud.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/parsers/wavelength.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/assemble_movie.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/l1_output_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/globus.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/interservice_bus.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/metadata_store.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/object_store.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/quality/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/quality/_base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/mixin/quality/_metrics.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/output_data_base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/parse_l0_input_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/quality_metrics.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/teardown.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/transfer_input_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/trial_catalog.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/trial_output_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/write_extra.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/write_l1.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tasks/write_l1_base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/__init__.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/conftest.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/mock_metadata_store.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_assemble_movie.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_assemble_quality.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_codecs.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_constants.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_construct_dataset_extras.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_cs_step.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_dkist_location.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_fits_access.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_flower_pot.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_fried_parameter.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_input_dataset.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_interservice_bus.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_interservice_bus_mixin.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_manual_processing.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_output_data_base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_parameters.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_parse_l0_input_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_publish_catalog_messages.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_quality.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_quality_mixin.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_scratch.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_submit_dataset_metadata.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_tags.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_task_name.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_task_parsing.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_teardown.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_transfer_input_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_transfer_l1_output_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_trial_catalog.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_trial_output_data.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_workflow_task_base.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/tests/test_write_l1.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common.egg-info/SOURCES.txt +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common.egg-info/dependency_links.txt +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common.egg-info/requires.txt +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common.egg-info/top_level.txt +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/Makefile +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/changelog.rst +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/conf.py +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/index.rst +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/landing_page.rst +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/make.bat +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/docs/requirements.txt +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/licenses/LICENSE.rst +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/pyproject.toml +0 -0
- {dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/setup.cfg +0 -0
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
v13.0.0 (2026-04-03)
|
|
2
|
+
====================
|
|
3
|
+
|
|
4
|
+
Bugfixes
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
- Update `*CadenceBuds` to correctly account for polarimetric data. Previously, the potentially different cadence
|
|
8
|
+
between modulation states was not considered when computing the cadence of L0 observations. (`#310 <https://bitbucket.org/dkistdc/dkist-processing-common/pull-requests/310>`__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
Misc
|
|
12
|
+
----
|
|
13
|
+
|
|
14
|
+
- *All* children of `L0FitsAccess` are now required to define the `modulator_state` attribute. If an instrument is not
|
|
15
|
+
polarimetric, setting this attribute to -1 is recommended. (`#310 <https://bitbucket.org/dkistdc/dkist-processing-common/pull-requests/310>`__)
|
|
16
|
+
|
|
17
|
+
|
|
1
18
|
v12.10.0 (2026-04-02)
|
|
2
19
|
=====================
|
|
3
20
|
|
|
@@ -13,7 +13,7 @@ from dkist_processing_common.parsers.single_value_single_key_flower import (
|
|
|
13
13
|
)
|
|
14
14
|
|
|
15
15
|
|
|
16
|
-
def passthrough_header_ip_task(fits_obj:
|
|
16
|
+
def passthrough_header_ip_task(fits_obj: FitsAccessBase) -> str:
|
|
17
17
|
"""
|
|
18
18
|
Simply read the IP task directly from the header.
|
|
19
19
|
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"""Time parser."""
|
|
2
2
|
|
|
3
|
+
from collections import defaultdict
|
|
3
4
|
from datetime import datetime
|
|
4
5
|
from datetime import timezone
|
|
5
6
|
from enum import StrEnum
|
|
7
|
+
from typing import Any
|
|
6
8
|
from typing import Callable
|
|
7
9
|
from typing import Type
|
|
8
10
|
|
|
@@ -110,83 +112,134 @@ class TaskDatetimeBudBase(ListStem):
|
|
|
110
112
|
return tuple(sorted(self.value_list))
|
|
111
113
|
|
|
112
114
|
|
|
113
|
-
class CadenceBudBase(
|
|
114
|
-
"""
|
|
115
|
+
class CadenceBudBase(ListStem):
|
|
116
|
+
"""
|
|
117
|
+
Base class for all Cadence Buds.
|
|
118
|
+
|
|
119
|
+
Despite subclassing `ListStem`, this class does not use the `list` storage provided by that class. Instead, a dictionary
|
|
120
|
+
mapping modulation state to a list of times is used, which allows us to compute cadence values properly for polarimetric
|
|
121
|
+
data.
|
|
122
|
+
|
|
123
|
+
Two functions must be provided: one for reducing all timestamps for a given modstate, and one for reducing the individual
|
|
124
|
+
modstate values into the final cadence value. In other words, we first compute the requested "cadence" value individually
|
|
125
|
+
for each modstate, and then combine the value for all mostates into a single value that will be used for the constant.
|
|
126
|
+
"""
|
|
115
127
|
|
|
116
|
-
def __init__(
|
|
128
|
+
def __init__(
|
|
129
|
+
self,
|
|
130
|
+
constant_name: str,
|
|
131
|
+
diff_reducing_function: Callable[[np.ndarray], np.floating[Any]],
|
|
132
|
+
modstate_reducing_function: Callable[[list[np.floating[Any]]], np.floating[Any]],
|
|
133
|
+
):
|
|
117
134
|
super().__init__(
|
|
118
135
|
stem_name=constant_name,
|
|
119
|
-
metadata_key=MetadataKey.time_obs,
|
|
120
|
-
ip_task_types=TaskName.observe,
|
|
121
136
|
)
|
|
137
|
+
self.header_parsing_function = passthrough_header_ip_task
|
|
138
|
+
self.time_objs_metadata_key = MetadataKey.time_obs.name
|
|
139
|
+
self.ip_task_type = TaskName.observe.value.casefold()
|
|
140
|
+
self.mapping = defaultdict(list)
|
|
141
|
+
self.diff_reduce_fcn = diff_reducing_function
|
|
142
|
+
self.mod_reduce_fcn = modstate_reducing_function
|
|
143
|
+
|
|
144
|
+
def setter(self, fits_obj: L0FitsAccess) -> str | Type[SpilledDirt]:
|
|
145
|
+
"""
|
|
146
|
+
Ingest a single `FitsAccess` object.
|
|
122
147
|
|
|
148
|
+
The object's timestamp is appended to the list of values associated with the object's modstate.
|
|
149
|
+
"""
|
|
150
|
+
if self.header_parsing_function(fits_obj).casefold() == self.ip_task_type:
|
|
151
|
+
modstate = fits_obj.modulator_state
|
|
123
152
|
|
|
124
|
-
|
|
125
|
-
|
|
153
|
+
timestamp = (
|
|
154
|
+
datetime.fromisoformat(getattr(fits_obj, self.time_objs_metadata_key))
|
|
155
|
+
.replace(tzinfo=timezone.utc)
|
|
156
|
+
.timestamp()
|
|
157
|
+
)
|
|
158
|
+
self.mapping[modstate].append(timestamp)
|
|
126
159
|
|
|
127
|
-
|
|
128
|
-
|
|
160
|
+
# Return values are important here; We have to return *something* if we're recording data we want to use.
|
|
161
|
+
# This string is that.
|
|
162
|
+
return "not used"
|
|
163
|
+
|
|
164
|
+
# And we have to return `SpilledDirt` if we didn't ingest this fits object
|
|
165
|
+
return SpilledDirt
|
|
129
166
|
|
|
130
|
-
def getter(self) -> np.
|
|
167
|
+
def getter(self) -> np.floating[Any]:
|
|
131
168
|
"""
|
|
132
|
-
|
|
169
|
+
Compute the cadence logic defined by the diff and modstate reducing functions.
|
|
133
170
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
171
|
+
For each modstate:
|
|
172
|
+
#. Sort the individual timestamps
|
|
173
|
+
#. Compute the `~numpy.diff` of this sorted list
|
|
174
|
+
#. Apply the ``diff_reduce_fcn`` to this diff array
|
|
175
|
+
|
|
176
|
+
Finally, apply the ``mod_reduce_fcn`` to the above results for all modstates to produce the final answer.
|
|
137
177
|
"""
|
|
138
|
-
|
|
178
|
+
per_modstate_values = [
|
|
179
|
+
self.diff_reduce_fcn(np.diff(sorted(time_list))) for time_list in self.mapping.values()
|
|
180
|
+
]
|
|
181
|
+
final_value = self.mod_reduce_fcn(per_modstate_values)
|
|
182
|
+
return final_value
|
|
139
183
|
|
|
140
184
|
|
|
141
|
-
class
|
|
142
|
-
"""
|
|
185
|
+
class AverageCadenceBud(CadenceBudBase):
|
|
186
|
+
"""
|
|
187
|
+
Class for the average cadence Bud.
|
|
188
|
+
|
|
189
|
+
The final value is the average across modstates of the average time difference within each modstate.
|
|
190
|
+
"""
|
|
143
191
|
|
|
144
192
|
def __init__(self):
|
|
145
|
-
super().__init__(
|
|
193
|
+
super().__init__(
|
|
194
|
+
constant_name=BudName.average_cadence,
|
|
195
|
+
diff_reducing_function=np.mean,
|
|
196
|
+
modstate_reducing_function=np.mean,
|
|
197
|
+
)
|
|
146
198
|
|
|
147
|
-
def getter(self) -> np.float64:
|
|
148
|
-
"""
|
|
149
|
-
Return the maximum cadence between frames.
|
|
150
|
-
|
|
151
|
-
Returns
|
|
152
|
-
-------
|
|
153
|
-
The maximum cadence between frames
|
|
154
|
-
"""
|
|
155
|
-
return np.max(np.diff(super().getter()))
|
|
156
199
|
|
|
200
|
+
class MaximumCadenceBud(CadenceBudBase):
|
|
201
|
+
"""
|
|
202
|
+
Class for the maximum cadence bud.
|
|
157
203
|
|
|
158
|
-
|
|
159
|
-
"""
|
|
204
|
+
The final value is the max across modstates of the max time difference within each modstate.
|
|
205
|
+
"""
|
|
160
206
|
|
|
161
207
|
def __init__(self):
|
|
162
|
-
super().__init__(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
208
|
+
super().__init__(
|
|
209
|
+
constant_name=BudName.maximum_cadence,
|
|
210
|
+
diff_reducing_function=np.max,
|
|
211
|
+
modstate_reducing_function=np.max,
|
|
212
|
+
)
|
|
167
213
|
|
|
168
|
-
Returns
|
|
169
|
-
-------
|
|
170
|
-
The minimum cadence between frames
|
|
171
|
-
"""
|
|
172
|
-
return np.min(np.diff(super().getter()))
|
|
173
214
|
|
|
215
|
+
class MinimumCadenceBud(CadenceBudBase):
|
|
216
|
+
"""
|
|
217
|
+
Class for the minimum cadence bud.
|
|
174
218
|
|
|
175
|
-
|
|
176
|
-
"""
|
|
219
|
+
The final value is the minimum across modstates of the minimum time difference within each modstate.
|
|
220
|
+
"""
|
|
177
221
|
|
|
178
222
|
def __init__(self):
|
|
179
|
-
super().__init__(
|
|
223
|
+
super().__init__(
|
|
224
|
+
constant_name=BudName.minimum_cadence,
|
|
225
|
+
diff_reducing_function=np.min,
|
|
226
|
+
modstate_reducing_function=np.min,
|
|
227
|
+
)
|
|
180
228
|
|
|
181
|
-
def getter(self) -> np.float64:
|
|
182
|
-
"""
|
|
183
|
-
Return the cadence variance between frames.
|
|
184
229
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
230
|
+
class VarianceCadenceBud(CadenceBudBase):
|
|
231
|
+
"""
|
|
232
|
+
Class for the variance cadence Bud.
|
|
233
|
+
|
|
234
|
+
The final value is the average across modstates of the variance time difference within each modstate.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
def __init__(self):
|
|
238
|
+
super().__init__(
|
|
239
|
+
constant_name=BudName.variance_cadence,
|
|
240
|
+
diff_reducing_function=np.var,
|
|
241
|
+
modstate_reducing_function=np.mean,
|
|
242
|
+
)
|
|
190
243
|
|
|
191
244
|
|
|
192
245
|
class TaskDateBeginBud(TaskDatetimeBudBase):
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import collections
|
|
2
2
|
from enum import StrEnum
|
|
3
3
|
from itertools import chain
|
|
4
|
+
from typing import Generator
|
|
4
5
|
|
|
5
6
|
import pytest
|
|
6
7
|
from astropy.io import fits
|
|
@@ -20,6 +21,7 @@ from dkist_processing_common.parsers.dsps_repeat import TotalDspsRepeatsBud
|
|
|
20
21
|
from dkist_processing_common.parsers.experiment_id_bud import ContributingExperimentIdsBud
|
|
21
22
|
from dkist_processing_common.parsers.experiment_id_bud import ExperimentIdBud
|
|
22
23
|
from dkist_processing_common.parsers.id_bud import TaskContributingIdsBud
|
|
24
|
+
from dkist_processing_common.parsers.l0_fits_access import AbstractProperty
|
|
23
25
|
from dkist_processing_common.parsers.lookup_bud import TaskTimeLookupBud
|
|
24
26
|
from dkist_processing_common.parsers.lookup_bud import TimeLookupBud
|
|
25
27
|
from dkist_processing_common.parsers.near_bud import NearFloatBud
|
|
@@ -75,9 +77,11 @@ class FitsReaderMetadataKey(StrEnum):
|
|
|
75
77
|
gos_polarizer_status = "GOSPOL"
|
|
76
78
|
wavelength = "LINEWAV"
|
|
77
79
|
roundable_time = "RTIME"
|
|
80
|
+
modulator_state = "MODSTATE"
|
|
78
81
|
|
|
79
82
|
|
|
80
83
|
class FitsReader(FitsAccessBase):
|
|
84
|
+
|
|
81
85
|
def __init__(self, hdu, name):
|
|
82
86
|
super().__init__(hdu, name)
|
|
83
87
|
self.thing_id: int = self.header.get(FitsReaderMetadataKey.thing_id)
|
|
@@ -112,10 +116,17 @@ class FitsReader(FitsAccessBase):
|
|
|
112
116
|
self.gos_polarizer_status: str = self.header.get(FitsReaderMetadataKey.gos_polarizer_status)
|
|
113
117
|
self.wavelength: str = self.header.get(FitsReaderMetadataKey.wavelength)
|
|
114
118
|
self.roundable_time: float = self.header.get(FitsReaderMetadataKey.roundable_time, 0.0)
|
|
119
|
+
self.modulator_state: int = -1
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class ModFitsReader(FitsReader):
|
|
123
|
+
def __init__(self, hdu, name):
|
|
124
|
+
super().__init__(hdu, name)
|
|
125
|
+
self.modulator_state: int = self.header.get(FitsReaderMetadataKey.modulator_state)
|
|
115
126
|
|
|
116
127
|
|
|
117
128
|
@pytest.fixture()
|
|
118
|
-
def basic_header_objs():
|
|
129
|
+
def basic_header_objs() -> Generator[FitsReader, None, None]:
|
|
119
130
|
header_dict = {
|
|
120
131
|
"thing0": fits.header.Header(
|
|
121
132
|
{
|
|
@@ -223,7 +234,7 @@ def basic_header_objs():
|
|
|
223
234
|
|
|
224
235
|
|
|
225
236
|
@pytest.fixture
|
|
226
|
-
def task_with_gains_header_objs():
|
|
237
|
+
def task_with_gains_header_objs() -> Generator[FitsReader, None, None]:
|
|
227
238
|
header_dict = {
|
|
228
239
|
"lamp_gain": fits.header.Header({"DKIST004": "gain", "GOSLVL3": "lamp", "GOSLAMP": "on"}),
|
|
229
240
|
"solar_gain": fits.header.Header({"DKIST004": "gain", "GOSLVL3": "clear"}),
|
|
@@ -238,7 +249,7 @@ def retarder_name():
|
|
|
238
249
|
|
|
239
250
|
|
|
240
251
|
@pytest.fixture
|
|
241
|
-
def task_with_polcal_header_objs(retarder_name):
|
|
252
|
+
def task_with_polcal_header_objs(retarder_name) -> Generator[FitsReader, None, None]:
|
|
242
253
|
header_dict = {
|
|
243
254
|
"polcal_dark": fits.header.Header(
|
|
244
255
|
{"DKIST004": "polcal", "GOSLVL0": "DarkShutter", "GOSPOL": "clear", "GOSRET": "clear"}
|
|
@@ -254,7 +265,7 @@ def task_with_polcal_header_objs(retarder_name):
|
|
|
254
265
|
|
|
255
266
|
|
|
256
267
|
@pytest.fixture()
|
|
257
|
-
def bad_header_objs():
|
|
268
|
+
def bad_header_objs() -> Generator[FitsReader, None, None]:
|
|
258
269
|
bad_headers = {
|
|
259
270
|
"thing0": fits.header.Header(
|
|
260
271
|
{
|
|
@@ -309,7 +320,7 @@ def bad_header_objs():
|
|
|
309
320
|
|
|
310
321
|
|
|
311
322
|
@pytest.fixture
|
|
312
|
-
def bad_polcal_header_objs():
|
|
323
|
+
def bad_polcal_header_objs() -> Generator[FitsReader, None, None]:
|
|
313
324
|
# I.e., GOSRET has multiple values
|
|
314
325
|
header_dict = {
|
|
315
326
|
"thing1": fits.header.Header({"DKIST004": "polcal", "GOSRET": "clear"}),
|
|
@@ -319,6 +330,52 @@ def bad_polcal_header_objs():
|
|
|
319
330
|
return (FitsReader.from_header(header, name=path) for path, header in header_dict.items())
|
|
320
331
|
|
|
321
332
|
|
|
333
|
+
@pytest.fixture
|
|
334
|
+
def modulated_cadence_header_objs() -> Generator[FitsReader, None, None]:
|
|
335
|
+
header_dict = {
|
|
336
|
+
"thing1": fits.Header(
|
|
337
|
+
{"MODSTATE": 1, "DATE-OBS": "2000-01-01T00:00:00", "DKIST004": "observe"}
|
|
338
|
+
),
|
|
339
|
+
"thing2": fits.Header(
|
|
340
|
+
{"MODSTATE": 1, "DATE-OBS": "2000-01-01T00:00:10", "DKIST004": "observe"}
|
|
341
|
+
),
|
|
342
|
+
"thing3": fits.Header(
|
|
343
|
+
{"MODSTATE": 1, "DATE-OBS": "2000-01-01T00:00:22", "DKIST004": "observe"}
|
|
344
|
+
),
|
|
345
|
+
"thing4": fits.Header(
|
|
346
|
+
{"MODSTATE": 2, "DATE-OBS": "2000-01-02T00:00:00", "DKIST004": "observe"}
|
|
347
|
+
),
|
|
348
|
+
"thing5": fits.Header(
|
|
349
|
+
{"MODSTATE": 2, "DATE-OBS": "2000-01-02T00:00:05", "DKIST004": "observe"}
|
|
350
|
+
),
|
|
351
|
+
"thing6": fits.Header(
|
|
352
|
+
{"MODSTATE": 2, "DATE-OBS": "2000-01-02T00:00:11", "DKIST004": "observe"}
|
|
353
|
+
),
|
|
354
|
+
"thing7": fits.Header(
|
|
355
|
+
{"MODSTATE": 3, "DATE-OBS": "2000-01-03T00:00:00", "DKIST004": "observe"}
|
|
356
|
+
),
|
|
357
|
+
"thing8": fits.Header(
|
|
358
|
+
{"MODSTATE": 3, "DATE-OBS": "2000-01-03T00:00:03", "DKIST004": "observe"}
|
|
359
|
+
),
|
|
360
|
+
"thing9": fits.Header(
|
|
361
|
+
{"MODSTATE": 3, "DATE-OBS": "2000-01-03T00:00:07", "DKIST004": "observe"}
|
|
362
|
+
),
|
|
363
|
+
"thing10": fits.Header(
|
|
364
|
+
{"MODSTATE": 3, "DATE-OBS": "2000-12-31T00:00:00", "DKIST004": "gain"}
|
|
365
|
+
),
|
|
366
|
+
}
|
|
367
|
+
return (ModFitsReader.from_header(header, name=path) for path, header in header_dict.items())
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
@pytest.fixture
|
|
371
|
+
def non_observe_header_objs() -> Generator[FitsReader, None, None]:
|
|
372
|
+
header_dict = {
|
|
373
|
+
"thing1": fits.Header({"DKIST004": "gain"}),
|
|
374
|
+
"thing2": fits.Header({"DKIST004": "dark"}),
|
|
375
|
+
}
|
|
376
|
+
return (ModFitsReader.from_header(header, name=path) for path, header in header_dict.items())
|
|
377
|
+
|
|
378
|
+
|
|
322
379
|
def test_unique_bud(basic_header_objs):
|
|
323
380
|
"""
|
|
324
381
|
Given: A set of headers with a constant value header key
|
|
@@ -874,7 +931,7 @@ def test_dsps_flower(basic_header_objs):
|
|
|
874
931
|
assert petals[1].keys == ["thing3"]
|
|
875
932
|
|
|
876
933
|
|
|
877
|
-
def test_average_cadence_bud(basic_header_objs):
|
|
934
|
+
def test_average_cadence_bud(basic_header_objs, modulated_cadence_header_objs):
|
|
878
935
|
"""
|
|
879
936
|
Given: A set of filepaths and associated headers with DATE-OBS keywords
|
|
880
937
|
When: Ingesting with the AverageCadenceBud
|
|
@@ -889,8 +946,15 @@ def test_average_cadence_bud(basic_header_objs):
|
|
|
889
946
|
# Because there are 3 observe frames in `basic_header_objs` spaced 1, and 2 seconds apart.
|
|
890
947
|
assert bud_obj.bud.value == 1.5
|
|
891
948
|
|
|
949
|
+
pol_bud_obj = AverageCadenceBud()
|
|
950
|
+
for fo in modulated_cadence_header_objs:
|
|
951
|
+
key = fo.name
|
|
952
|
+
pol_bud_obj.update(key, fo)
|
|
953
|
+
|
|
954
|
+
assert pol_bud_obj.bud.value == 20 / 3
|
|
955
|
+
|
|
892
956
|
|
|
893
|
-
def test_max_cadence_bud(basic_header_objs):
|
|
957
|
+
def test_max_cadence_bud(basic_header_objs, modulated_cadence_header_objs):
|
|
894
958
|
"""
|
|
895
959
|
Given: A set of filepaths and associated headers with DATE-OBS keywords
|
|
896
960
|
When: Ingesting with the MaxCadenceBud
|
|
@@ -905,8 +969,15 @@ def test_max_cadence_bud(basic_header_objs):
|
|
|
905
969
|
# Because there are 3 observe frames in `basic_header_objs` spaced 1, and 2 seconds apart.
|
|
906
970
|
assert bud_obj.bud.value == 2
|
|
907
971
|
|
|
972
|
+
pol_bud_obj = MaximumCadenceBud()
|
|
973
|
+
for fo in modulated_cadence_header_objs:
|
|
974
|
+
key = fo.name
|
|
975
|
+
pol_bud_obj.update(key, fo)
|
|
976
|
+
|
|
977
|
+
assert pol_bud_obj.bud.value == 12
|
|
978
|
+
|
|
908
979
|
|
|
909
|
-
def test_minimum_cadence_bud(basic_header_objs):
|
|
980
|
+
def test_minimum_cadence_bud(basic_header_objs, modulated_cadence_header_objs):
|
|
910
981
|
"""
|
|
911
982
|
Given: A set of filepaths and associated headers with DATE-OBS keywords
|
|
912
983
|
When: Ingesting with the MinimumCadenceBud
|
|
@@ -921,8 +992,15 @@ def test_minimum_cadence_bud(basic_header_objs):
|
|
|
921
992
|
# Because there are 3 observe frames in `basic_header_objs` spaced 1, and 2 seconds apart.
|
|
922
993
|
assert bud_obj.bud.value == 1
|
|
923
994
|
|
|
995
|
+
pol_bud_obj = MinimumCadenceBud()
|
|
996
|
+
for fo in modulated_cadence_header_objs:
|
|
997
|
+
key = fo.name
|
|
998
|
+
pol_bud_obj.update(key, fo)
|
|
999
|
+
|
|
1000
|
+
assert pol_bud_obj.bud.value == 3
|
|
924
1001
|
|
|
925
|
-
|
|
1002
|
+
|
|
1003
|
+
def test_variance_cadence_bud(basic_header_objs, modulated_cadence_header_objs):
|
|
926
1004
|
"""
|
|
927
1005
|
Given: A set of filepaths and associated headers with DATE-OBS keywords
|
|
928
1006
|
When: Ingesting with the VarianceCadenceBud
|
|
@@ -937,6 +1015,37 @@ def test_variance_cadence_bud(basic_header_objs):
|
|
|
937
1015
|
# Because there are 3 observe frames in `basic_header_objs` spaced 1, and 2 seconds apart.
|
|
938
1016
|
assert bud_obj.bud.value == 0.25
|
|
939
1017
|
|
|
1018
|
+
pol_bud_obj = VarianceCadenceBud()
|
|
1019
|
+
for fo in modulated_cadence_header_objs:
|
|
1020
|
+
key = fo.name
|
|
1021
|
+
pol_bud_obj.update(key, fo)
|
|
1022
|
+
|
|
1023
|
+
assert pol_bud_obj.bud.value == 0.5
|
|
1024
|
+
|
|
1025
|
+
|
|
1026
|
+
def test_cadence_buds_no_observes(non_observe_header_objs):
|
|
1027
|
+
"""
|
|
1028
|
+
Given: A set of filepaths and headers that contain no "observe" frames
|
|
1029
|
+
When: Ingesting these headers with the *CadenceBuds and checking if there are values to be picked
|
|
1030
|
+
Then: None of the Buds "can_be_picked"
|
|
1031
|
+
"""
|
|
1032
|
+
avg_bud = AverageCadenceBud()
|
|
1033
|
+
min_bud = MinimumCadenceBud()
|
|
1034
|
+
max_bud = MaximumCadenceBud()
|
|
1035
|
+
var_bud = VarianceCadenceBud()
|
|
1036
|
+
|
|
1037
|
+
for fo in non_observe_header_objs:
|
|
1038
|
+
key = fo.name
|
|
1039
|
+
avg_bud.update(key, fo)
|
|
1040
|
+
min_bud.update(key, fo)
|
|
1041
|
+
max_bud.update(key, fo)
|
|
1042
|
+
var_bud.update(key, fo)
|
|
1043
|
+
|
|
1044
|
+
assert not avg_bud.can_be_picked
|
|
1045
|
+
assert not min_bud.can_be_picked
|
|
1046
|
+
assert not max_bud.can_be_picked
|
|
1047
|
+
assert not var_bud.can_be_picked
|
|
1048
|
+
|
|
940
1049
|
|
|
941
1050
|
def test_task_date_begin_bud(basic_header_objs):
|
|
942
1051
|
"""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dkist_processing_common-12.10.0 → dkist_processing_common-13.0.0}/dkist_processing_common/manual.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|