dkist-processing-visp 2.20.14__py3-none-any.whl → 5.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dkist_processing_visp/__init__.py +1 -0
- dkist_processing_visp/config.py +1 -0
- dkist_processing_visp/models/constants.py +61 -20
- dkist_processing_visp/models/fits_access.py +20 -0
- dkist_processing_visp/models/metric_code.py +10 -0
- dkist_processing_visp/models/parameters.py +129 -24
- dkist_processing_visp/models/tags.py +22 -1
- dkist_processing_visp/models/task_name.py +1 -0
- dkist_processing_visp/parsers/map_repeats.py +1 -0
- dkist_processing_visp/parsers/modulator_states.py +1 -0
- dkist_processing_visp/parsers/polarimeter_mode.py +4 -2
- dkist_processing_visp/parsers/raster_step.py +4 -1
- dkist_processing_visp/parsers/spectrograph_configuration.py +75 -0
- dkist_processing_visp/parsers/time.py +24 -14
- dkist_processing_visp/parsers/visp_l0_fits_access.py +19 -8
- dkist_processing_visp/parsers/visp_l1_fits_access.py +1 -0
- dkist_processing_visp/tasks/__init__.py +1 -0
- dkist_processing_visp/tasks/assemble_movie.py +1 -0
- dkist_processing_visp/tasks/background_light.py +2 -1
- dkist_processing_visp/tasks/dark.py +5 -4
- dkist_processing_visp/tasks/geometric.py +132 -20
- dkist_processing_visp/tasks/instrument_polarization.py +128 -18
- dkist_processing_visp/tasks/l1_output_data.py +203 -0
- dkist_processing_visp/tasks/lamp.py +53 -93
- dkist_processing_visp/tasks/make_movie_frames.py +8 -6
- dkist_processing_visp/tasks/mixin/beam_access.py +1 -0
- dkist_processing_visp/tasks/mixin/corrections.py +54 -4
- dkist_processing_visp/tasks/mixin/downsample.py +1 -0
- dkist_processing_visp/tasks/parse.py +50 -17
- dkist_processing_visp/tasks/quality_metrics.py +5 -4
- dkist_processing_visp/tasks/science.py +126 -46
- dkist_processing_visp/tasks/solar.py +896 -456
- dkist_processing_visp/tasks/visp_base.py +4 -3
- dkist_processing_visp/tasks/write_l1.py +38 -10
- dkist_processing_visp/tests/conftest.py +145 -47
- dkist_processing_visp/tests/header_models.py +157 -20
- dkist_processing_visp/tests/local_trial_workflows/l0_cals_only.py +21 -78
- dkist_processing_visp/tests/local_trial_workflows/l0_polcals_as_science.py +421 -0
- dkist_processing_visp/tests/local_trial_workflows/l0_solar_gain_as_science.py +387 -0
- dkist_processing_visp/tests/local_trial_workflows/l0_to_l1.py +18 -75
- dkist_processing_visp/tests/local_trial_workflows/local_trial_helpers.py +346 -14
- dkist_processing_visp/tests/test_assemble_movie.py +2 -3
- dkist_processing_visp/tests/test_assemble_quality.py +89 -4
- dkist_processing_visp/tests/test_background_light.py +51 -44
- dkist_processing_visp/tests/test_dark.py +4 -3
- dkist_processing_visp/tests/test_downsample.py +1 -0
- dkist_processing_visp/tests/test_fits_access.py +43 -0
- dkist_processing_visp/tests/test_geometric.py +45 -4
- dkist_processing_visp/tests/test_instrument_polarization.py +72 -9
- dkist_processing_visp/tests/test_lamp.py +22 -26
- dkist_processing_visp/tests/test_make_movie_frames.py +4 -4
- dkist_processing_visp/tests/test_map_repeats.py +3 -1
- dkist_processing_visp/tests/test_parameters.py +122 -21
- dkist_processing_visp/tests/test_parse.py +164 -18
- dkist_processing_visp/tests/test_quality.py +3 -4
- dkist_processing_visp/tests/test_science.py +113 -15
- dkist_processing_visp/tests/test_solar.py +318 -99
- dkist_processing_visp/tests/test_visp_constants.py +38 -8
- dkist_processing_visp/tests/test_workflows.py +1 -0
- dkist_processing_visp/tests/test_write_l1.py +22 -3
- dkist_processing_visp/workflows/__init__.py +1 -0
- dkist_processing_visp/workflows/l0_processing.py +10 -3
- dkist_processing_visp/workflows/trial_workflows.py +8 -2
- dkist_processing_visp-5.1.1.dist-info/METADATA +552 -0
- dkist_processing_visp-5.1.1.dist-info/RECORD +94 -0
- {dkist_processing_visp-2.20.14.dist-info → dkist_processing_visp-5.1.1.dist-info}/WHEEL +1 -1
- docs/conf.py +5 -1
- docs/gain_correction.rst +52 -44
- docs/science_calibration.rst +7 -0
- dkist_processing_visp/tasks/mixin/line_zones.py +0 -115
- dkist_processing_visp-2.20.14.dist-info/METADATA +0 -196
- dkist_processing_visp-2.20.14.dist-info/RECORD +0 -89
- {dkist_processing_visp-2.20.14.dist-info → dkist_processing_visp-5.1.1.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"""Visp make movie frames task."""
|
|
2
|
+
|
|
2
3
|
import numpy as np
|
|
3
4
|
from astropy.io import fits
|
|
4
5
|
from astropy.visualization import ZScaleInterval
|
|
5
6
|
from dkist_processing_common.codecs.fits import fits_access_decoder
|
|
6
7
|
from dkist_processing_common.codecs.fits import fits_array_encoder
|
|
8
|
+
from dkist_processing_common.models.fits_access import MetadataKey
|
|
7
9
|
from dkist_service_configuration.logging import logger
|
|
8
10
|
|
|
9
11
|
from dkist_processing_visp.models.tags import VispTag
|
|
@@ -46,7 +48,7 @@ class MakeVispMovieFrames(VispTaskBase):
|
|
|
46
48
|
stokes_states = ["I", "Q", "U", "V"]
|
|
47
49
|
# Loop over the number of raster scans
|
|
48
50
|
for map_scan in range(1, self.constants.num_map_scans + 1):
|
|
49
|
-
with self.
|
|
51
|
+
with self.telemetry_span(f"Making movie frame for {map_scan = }"):
|
|
50
52
|
instrument_set = set()
|
|
51
53
|
wavelength_set = set()
|
|
52
54
|
time_obs = []
|
|
@@ -77,7 +79,7 @@ class MakeVispMovieFrames(VispTaskBase):
|
|
|
77
79
|
fits_access_class=VispL1FitsAccess,
|
|
78
80
|
)
|
|
79
81
|
)
|
|
80
|
-
data = calibrated_frame.data
|
|
82
|
+
data = np.nan_to_num(calibrated_frame.data, nan=0)
|
|
81
83
|
if self.constants.num_raster_steps == 1:
|
|
82
84
|
logger.info(
|
|
83
85
|
"Only a single raster step found. Making a spectral movie."
|
|
@@ -120,16 +122,16 @@ class MakeVispMovieFrames(VispTaskBase):
|
|
|
120
122
|
f"There should only be one instrument value in the headers. "
|
|
121
123
|
f"Found {len(instrument_set)}: {instrument_set=}"
|
|
122
124
|
)
|
|
123
|
-
header[
|
|
125
|
+
header[MetadataKey.instrument] = instrument_set.pop()
|
|
124
126
|
# The timestamp of a movie frame will be the time of raster scan start
|
|
125
|
-
header[
|
|
127
|
+
header[MetadataKey.time_obs] = time_obs[0]
|
|
126
128
|
# Make sure only one wavelength value was found
|
|
127
129
|
if len(wavelength_set) != 1:
|
|
128
130
|
raise ValueError(
|
|
129
131
|
f"There should only be one wavelength value in the headers. "
|
|
130
132
|
f"Found {len(wavelength_set)}: {wavelength_set=}"
|
|
131
133
|
)
|
|
132
|
-
header[
|
|
134
|
+
header[MetadataKey.wavelength] = wavelength_set.pop()
|
|
133
135
|
# Write the movie frame file to disk and tag it, normalizing across stokes intensities
|
|
134
136
|
if is_polarized:
|
|
135
137
|
i_norm = ZScaleInterval()(stokes_i_data)
|
|
@@ -146,7 +148,7 @@ class MakeVispMovieFrames(VispTaskBase):
|
|
|
146
148
|
else:
|
|
147
149
|
movie_frame_data = stokes_i_data
|
|
148
150
|
|
|
149
|
-
with self.
|
|
151
|
+
with self.telemetry_span(f"Writing movie frame for {map_scan = }"):
|
|
150
152
|
self.write(
|
|
151
153
|
data=np.asarray(movie_frame_data),
|
|
152
154
|
tags=[
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Helper for ViSP array corrections."""
|
|
2
|
+
|
|
2
3
|
from typing import Generator
|
|
3
4
|
from typing import Iterable
|
|
4
5
|
|
|
@@ -16,6 +17,9 @@ class CorrectionsMixin:
|
|
|
16
17
|
arrays: Iterable[np.ndarray] | np.ndarray,
|
|
17
18
|
shift: np.ndarray = np.zeros(2),
|
|
18
19
|
angle: float = 0.0,
|
|
20
|
+
mode: str = "edge",
|
|
21
|
+
order: int = 5,
|
|
22
|
+
cval: float = np.nan,
|
|
19
23
|
) -> Generator[np.ndarray, None, None]:
|
|
20
24
|
"""
|
|
21
25
|
Shift and then rotate data.
|
|
@@ -34,6 +38,24 @@ class CorrectionsMixin:
|
|
|
34
38
|
angle : float
|
|
35
39
|
The angle (in radians) between slit hairlines and pixel axes.
|
|
36
40
|
|
|
41
|
+
mode : {'constant', 'edge', 'symmetric', 'reflect', 'wrap'}
|
|
42
|
+
Points outside the boundaries of the input are filled according
|
|
43
|
+
to the given mode. Modes match the behaviour of `numpy.pad`.
|
|
44
|
+
|
|
45
|
+
order : int
|
|
46
|
+
The order of interpolation. The order has to be in the range 0-5:
|
|
47
|
+
- 0: Nearest-neighbor
|
|
48
|
+
- 1: Bi-linear (default)
|
|
49
|
+
- 2: Bi-quadratic
|
|
50
|
+
- 3: Bi-cubic
|
|
51
|
+
- 4: Bi-quartic
|
|
52
|
+
- 5: Bi-quintic
|
|
53
|
+
|
|
54
|
+
cval : float
|
|
55
|
+
Used in conjunction with mode 'constant', the value outside
|
|
56
|
+
the image boundaries.
|
|
57
|
+
|
|
58
|
+
|
|
37
59
|
Returns
|
|
38
60
|
-------
|
|
39
61
|
Generator
|
|
@@ -45,12 +67,21 @@ class CorrectionsMixin:
|
|
|
45
67
|
array[np.where(array == np.inf)] = np.max(array[np.isfinite(array)])
|
|
46
68
|
array[np.where(array == -np.inf)] = np.min(array[np.isfinite(array)])
|
|
47
69
|
array[np.isnan(array)] = np.nanmedian(array)
|
|
48
|
-
translated = affine_transform_arrays(
|
|
49
|
-
|
|
70
|
+
translated = affine_transform_arrays(
|
|
71
|
+
array, translation=-shift, mode=mode, order=order, cval=cval
|
|
72
|
+
)
|
|
73
|
+
yield next(
|
|
74
|
+
rotate_arrays_about_point(
|
|
75
|
+
translated, angle=-angle, mode=mode, order=order, cval=cval
|
|
76
|
+
)
|
|
77
|
+
)
|
|
50
78
|
|
|
51
79
|
@staticmethod
|
|
52
80
|
def corrections_remove_spec_geometry(
|
|
53
|
-
arrays: Iterable[np.ndarray] | np.ndarray,
|
|
81
|
+
arrays: Iterable[np.ndarray] | np.ndarray,
|
|
82
|
+
spec_shift: np.ndarray,
|
|
83
|
+
cval: float | None = None,
|
|
84
|
+
order: int = 3,
|
|
54
85
|
) -> Generator[np.ndarray, None, None]:
|
|
55
86
|
"""
|
|
56
87
|
Remove spectral curvature.
|
|
@@ -66,6 +97,19 @@ class CorrectionsMixin:
|
|
|
66
97
|
Array with shape (X), where X is the number of pixels in the spatial dimension.
|
|
67
98
|
This dimension gives the spectral shift.
|
|
68
99
|
|
|
100
|
+
order : int
|
|
101
|
+
The order of interpolation. The order has to be in the range 0-5:
|
|
102
|
+
- 0: Nearest-neighbor
|
|
103
|
+
- 1: Bi-linear (default)
|
|
104
|
+
- 2: Bi-quadratic
|
|
105
|
+
- 3: Bi-cubic
|
|
106
|
+
- 4: Bi-quartic
|
|
107
|
+
- 5: Bi-quintic
|
|
108
|
+
|
|
109
|
+
cval : float
|
|
110
|
+
Used in conjunction with mode 'constant', the value outside
|
|
111
|
+
the image boundaries.
|
|
112
|
+
|
|
69
113
|
Returns
|
|
70
114
|
-------
|
|
71
115
|
Generator
|
|
@@ -77,8 +121,14 @@ class CorrectionsMixin:
|
|
|
77
121
|
numy = array.shape[1]
|
|
78
122
|
array_output = np.zeros(array.shape)
|
|
79
123
|
for j in range(numy):
|
|
124
|
+
if cval is None:
|
|
125
|
+
cval = np.nanmedian(array[:, j])
|
|
80
126
|
array_output[:, j] = spnd.shift(
|
|
81
|
-
array[:, j],
|
|
127
|
+
array[:, j],
|
|
128
|
+
-spec_shift[j],
|
|
129
|
+
mode="constant",
|
|
130
|
+
cval=cval,
|
|
131
|
+
order=order,
|
|
82
132
|
)
|
|
83
133
|
yield array_output
|
|
84
134
|
|
|
@@ -1,23 +1,28 @@
|
|
|
1
1
|
"""ViSP parse task."""
|
|
2
|
+
|
|
2
3
|
from typing import TypeVar
|
|
3
4
|
|
|
5
|
+
from dkist_processing_common.models.fits_access import MetadataKey
|
|
4
6
|
from dkist_processing_common.models.flower_pot import Stem
|
|
5
7
|
from dkist_processing_common.models.task_name import TaskName
|
|
6
8
|
from dkist_processing_common.parsers.cs_step import CSStepFlower
|
|
7
9
|
from dkist_processing_common.parsers.cs_step import NumCSStepBud
|
|
8
|
-
from dkist_processing_common.parsers.
|
|
10
|
+
from dkist_processing_common.parsers.retarder import RetarderNameBud
|
|
11
|
+
from dkist_processing_common.parsers.task import PolcalTaskFlower
|
|
9
12
|
from dkist_processing_common.parsers.task import TaskTypeFlower
|
|
13
|
+
from dkist_processing_common.parsers.task import parse_header_ip_task_with_gains
|
|
10
14
|
from dkist_processing_common.parsers.time import ExposureTimeFlower
|
|
11
15
|
from dkist_processing_common.parsers.time import ObsIpStartTimeBud
|
|
12
16
|
from dkist_processing_common.parsers.time import ReadoutExpTimeFlower
|
|
13
17
|
from dkist_processing_common.parsers.time import TaskExposureTimesBud
|
|
14
18
|
from dkist_processing_common.parsers.time import TaskReadoutExpTimesBud
|
|
19
|
+
from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
|
|
15
20
|
from dkist_processing_common.parsers.unique_bud import UniqueBud
|
|
16
21
|
from dkist_processing_common.parsers.wavelength import ObserveWavelengthBud
|
|
17
22
|
from dkist_processing_common.tasks import ParseL0InputDataBase
|
|
18
|
-
from dkist_processing_common.tasks.mixin.input_dataset import InputDatasetMixin
|
|
19
23
|
|
|
20
24
|
from dkist_processing_visp.models.constants import VispBudName
|
|
25
|
+
from dkist_processing_visp.models.fits_access import VispMetadataKey
|
|
21
26
|
from dkist_processing_visp.models.parameters import VispParsingParameters
|
|
22
27
|
from dkist_processing_visp.parsers.map_repeats import MapScanFlower
|
|
23
28
|
from dkist_processing_visp.parsers.map_repeats import NumMapScansBud
|
|
@@ -26,15 +31,17 @@ from dkist_processing_visp.parsers.modulator_states import NumberModulatorStates
|
|
|
26
31
|
from dkist_processing_visp.parsers.polarimeter_mode import PolarimeterModeBud
|
|
27
32
|
from dkist_processing_visp.parsers.raster_step import RasterScanStepFlower
|
|
28
33
|
from dkist_processing_visp.parsers.raster_step import TotalRasterStepsBud
|
|
34
|
+
from dkist_processing_visp.parsers.spectrograph_configuration import IncidentLightAngleBud
|
|
35
|
+
from dkist_processing_visp.parsers.spectrograph_configuration import ReflectedLightAngleBud
|
|
29
36
|
from dkist_processing_visp.parsers.time import DarkReadoutExpTimePickyBud
|
|
30
|
-
from dkist_processing_visp.parsers.time import
|
|
37
|
+
from dkist_processing_visp.parsers.time import NonDarkNonPolcalTaskReadoutExpTimesBud
|
|
31
38
|
from dkist_processing_visp.parsers.visp_l0_fits_access import VispL0FitsAccess
|
|
32
39
|
|
|
33
40
|
S = TypeVar("S", bound=Stem)
|
|
34
41
|
__all__ = ["ParseL0VispInputData"]
|
|
35
42
|
|
|
36
43
|
|
|
37
|
-
class ParseL0VispInputData(ParseL0InputDataBase
|
|
44
|
+
class ParseL0VispInputData(ParseL0InputDataBase):
|
|
38
45
|
"""
|
|
39
46
|
Parse input ViSP data. Subclassed from the ParseL0InputDataBase task in dkist_processing_common to add ViSP specific parameters.
|
|
40
47
|
|
|
@@ -60,7 +67,7 @@ class ParseL0VispInputData(ParseL0InputDataBase, InputDatasetMixin):
|
|
|
60
67
|
workflow_name=workflow_name,
|
|
61
68
|
workflow_version=workflow_version,
|
|
62
69
|
)
|
|
63
|
-
self.parameters = VispParsingParameters(self.
|
|
70
|
+
self.parameters = VispParsingParameters(scratch=self.scratch)
|
|
64
71
|
|
|
65
72
|
@property
|
|
66
73
|
def fits_parsing_class(self):
|
|
@@ -71,6 +78,7 @@ class ParseL0VispInputData(ParseL0InputDataBase, InputDatasetMixin):
|
|
|
71
78
|
def constant_buds(self) -> list[S]:
|
|
72
79
|
"""Add ViSP specific constants to common constants."""
|
|
73
80
|
return super().constant_buds + [
|
|
81
|
+
UniqueBud(constant_name=VispBudName.arm_id.value, metadata_key=VispMetadataKey.arm_id),
|
|
74
82
|
NumMapScansBud(),
|
|
75
83
|
TotalRasterStepsBud(),
|
|
76
84
|
NumCSStepBud(self.parameters.max_cs_step_time_sec),
|
|
@@ -78,51 +86,75 @@ class ParseL0VispInputData(ParseL0InputDataBase, InputDatasetMixin):
|
|
|
78
86
|
NumberModulatorStatesBud(),
|
|
79
87
|
ObserveWavelengthBud(),
|
|
80
88
|
PolarimeterModeBud(),
|
|
81
|
-
|
|
89
|
+
RetarderNameBud(),
|
|
90
|
+
NonDarkNonPolcalTaskReadoutExpTimesBud(),
|
|
82
91
|
DarkReadoutExpTimePickyBud(),
|
|
92
|
+
IncidentLightAngleBud(),
|
|
93
|
+
ReflectedLightAngleBud(),
|
|
94
|
+
TaskUniqueBud(
|
|
95
|
+
constant_name=VispBudName.grating_constant_inverse_mm.value,
|
|
96
|
+
metadata_key=VispMetadataKey.grating_constant_inverse_mm,
|
|
97
|
+
ip_task_types=[TaskName.observe.value, TaskName.solar_gain.value],
|
|
98
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
99
|
+
),
|
|
100
|
+
TaskUniqueBud(
|
|
101
|
+
constant_name=VispBudName.solar_gain_ip_start_time.value,
|
|
102
|
+
metadata_key=MetadataKey.ip_start_time,
|
|
103
|
+
ip_task_types=TaskName.solar_gain,
|
|
104
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
105
|
+
),
|
|
83
106
|
TaskExposureTimesBud(
|
|
84
107
|
stem_name=VispBudName.lamp_exposure_times.value,
|
|
85
|
-
|
|
108
|
+
ip_task_types=TaskName.lamp_gain.value,
|
|
86
109
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
87
110
|
),
|
|
88
111
|
TaskExposureTimesBud(
|
|
89
112
|
stem_name=VispBudName.solar_exposure_times.value,
|
|
90
|
-
|
|
113
|
+
ip_task_types=TaskName.solar_gain.value,
|
|
91
114
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
92
115
|
),
|
|
93
116
|
TaskExposureTimesBud(
|
|
94
117
|
stem_name=VispBudName.observe_exposure_times.value,
|
|
95
|
-
|
|
118
|
+
ip_task_types=TaskName.observe.value,
|
|
96
119
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
97
120
|
),
|
|
98
121
|
TaskExposureTimesBud(
|
|
99
122
|
stem_name=VispBudName.polcal_exposure_times.value,
|
|
100
|
-
|
|
123
|
+
ip_task_types=TaskName.polcal.value,
|
|
101
124
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
102
125
|
),
|
|
103
126
|
TaskReadoutExpTimesBud(
|
|
104
127
|
stem_name=VispBudName.lamp_readout_exp_times.value,
|
|
105
|
-
|
|
128
|
+
ip_task_types=TaskName.lamp_gain.value,
|
|
106
129
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
107
130
|
),
|
|
108
131
|
TaskReadoutExpTimesBud(
|
|
109
132
|
stem_name=VispBudName.solar_readout_exp_times.value,
|
|
110
|
-
|
|
133
|
+
ip_task_types=TaskName.solar_gain.value,
|
|
111
134
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
112
135
|
),
|
|
113
136
|
TaskReadoutExpTimesBud(
|
|
114
137
|
stem_name=VispBudName.observe_readout_exp_times.value,
|
|
115
|
-
|
|
138
|
+
ip_task_types=TaskName.observe.value,
|
|
116
139
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
117
140
|
),
|
|
118
141
|
TaskReadoutExpTimesBud(
|
|
119
142
|
stem_name=VispBudName.polcal_readout_exp_times.value,
|
|
120
|
-
|
|
143
|
+
ip_task_types=TaskName.polcal.value,
|
|
121
144
|
header_task_parsing_func=parse_header_ip_task_with_gains,
|
|
122
145
|
),
|
|
123
|
-
UniqueBud(
|
|
124
|
-
|
|
125
|
-
|
|
146
|
+
UniqueBud(
|
|
147
|
+
constant_name=VispBudName.axis_1_type.value,
|
|
148
|
+
metadata_key=VispMetadataKey.axis_1_type,
|
|
149
|
+
),
|
|
150
|
+
UniqueBud(
|
|
151
|
+
constant_name=VispBudName.axis_2_type.value,
|
|
152
|
+
metadata_key=VispMetadataKey.axis_2_type,
|
|
153
|
+
),
|
|
154
|
+
UniqueBud(
|
|
155
|
+
constant_name=VispBudName.axis_3_type.value,
|
|
156
|
+
metadata_key=VispMetadataKey.axis_3_type,
|
|
157
|
+
),
|
|
126
158
|
]
|
|
127
159
|
|
|
128
160
|
@property
|
|
@@ -132,6 +164,7 @@ class ParseL0VispInputData(ParseL0InputDataBase, InputDatasetMixin):
|
|
|
132
164
|
CSStepFlower(max_cs_step_time_sec=self.parameters.max_cs_step_time_sec),
|
|
133
165
|
MapScanFlower(),
|
|
134
166
|
TaskTypeFlower(header_task_parsing_func=parse_header_ip_task_with_gains),
|
|
167
|
+
PolcalTaskFlower(),
|
|
135
168
|
RasterScanStepFlower(),
|
|
136
169
|
ModulatorStateFlower(),
|
|
137
170
|
ExposureTimeFlower(),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""ViSP quality metrics task."""
|
|
2
|
+
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from dataclasses import field
|
|
4
5
|
from typing import Iterable
|
|
@@ -105,7 +106,7 @@ class VispL1QualityMetrics(VispTaskBase, QualityMixin):
|
|
|
105
106
|
|
|
106
107
|
def compute_sensitivity(self) -> None:
|
|
107
108
|
"""Compute RMS noise and sensitivity estimate for L1 Visp frames."""
|
|
108
|
-
with self.
|
|
109
|
+
with self.telemetry_span("Calculating polarization metrics"):
|
|
109
110
|
all_datetimes = []
|
|
110
111
|
all_I_sensitivity = []
|
|
111
112
|
all_Q_sensitivity = []
|
|
@@ -161,7 +162,7 @@ class VispL1QualityMetrics(VispTaskBase, QualityMixin):
|
|
|
161
162
|
continue
|
|
162
163
|
|
|
163
164
|
# compute sensitivity for this Stokes parameter
|
|
164
|
-
data_list.append(np.
|
|
165
|
+
data_list.append(np.nanstd(stokes_frame.data) / stokesI_med)
|
|
165
166
|
|
|
166
167
|
all_datetimes.append(Time(np.mean(polarization_data.datetimes), format="mjd").isot)
|
|
167
168
|
for target, source in zip(
|
|
@@ -173,7 +174,7 @@ class VispL1QualityMetrics(VispTaskBase, QualityMixin):
|
|
|
173
174
|
continue
|
|
174
175
|
target.append(np.mean(source))
|
|
175
176
|
|
|
176
|
-
with self.
|
|
177
|
+
with self.telemetry_span("Sending lists for storage"):
|
|
177
178
|
for stokes_index, stokes_noise in zip(
|
|
178
179
|
("I", "Q", "U", "V"),
|
|
179
180
|
(all_I_sensitivity, all_Q_sensitivity, all_U_sensitivity, all_V_sensitivity),
|
|
@@ -186,7 +187,7 @@ class VispL1QualityMetrics(VispTaskBase, QualityMixin):
|
|
|
186
187
|
|
|
187
188
|
def compute_noise(self):
|
|
188
189
|
"""Compute noise in data."""
|
|
189
|
-
with self.
|
|
190
|
+
with self.telemetry_span("Calculating L1 ViSP noise metrics"):
|
|
190
191
|
for stokes in ["I", "Q", "U", "V"]:
|
|
191
192
|
tags = [VispTag.calibrated(), VispTag.frame(), VispTag.stokes(stokes)]
|
|
192
193
|
if self.scratch.count_all(tags=tags) > 0:
|