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,14 +1,14 @@
|
|
|
1
1
|
"""ViSP base class."""
|
|
2
|
+
|
|
2
3
|
from abc import ABC
|
|
3
4
|
|
|
4
5
|
from dkist_processing_common.tasks import WorkflowTaskBase
|
|
5
|
-
from dkist_processing_common.tasks.mixin.input_dataset import InputDatasetMixin
|
|
6
6
|
|
|
7
7
|
from dkist_processing_visp.models.constants import VispConstants
|
|
8
8
|
from dkist_processing_visp.models.parameters import VispParameters
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
class VispTaskBase(WorkflowTaskBase,
|
|
11
|
+
class VispTaskBase(WorkflowTaskBase, ABC):
|
|
12
12
|
"""
|
|
13
13
|
Task class for base ViSP tasks.
|
|
14
14
|
|
|
@@ -42,7 +42,8 @@ class VispTaskBase(WorkflowTaskBase, InputDatasetMixin, ABC):
|
|
|
42
42
|
workflow_version=workflow_version,
|
|
43
43
|
)
|
|
44
44
|
self.parameters = VispParameters(
|
|
45
|
-
self.
|
|
45
|
+
scratch=self.scratch,
|
|
46
46
|
obs_ip_start_time=self.constants.obs_ip_start_time,
|
|
47
47
|
wavelength=self.constants.wavelength,
|
|
48
|
+
arm_id=self.constants.arm_id,
|
|
48
49
|
)
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"""Visp write L1 task."""
|
|
2
|
+
|
|
2
3
|
from functools import cache
|
|
3
4
|
from typing import Literal
|
|
4
5
|
|
|
5
6
|
import astropy.units as u
|
|
6
7
|
from astropy.io import fits
|
|
8
|
+
from dkist_processing_common.models.fits_access import MetadataKey
|
|
7
9
|
from dkist_processing_common.tasks import WriteL1Frame
|
|
8
10
|
from dkist_processing_common.tasks.write_l1 import WavelengthRange
|
|
9
11
|
from dkist_service_configuration.logging import logger
|
|
10
12
|
|
|
11
13
|
from dkist_processing_visp.models.constants import VispConstants
|
|
14
|
+
from dkist_processing_visp.models.fits_access import VispMetadataKey
|
|
12
15
|
|
|
13
16
|
cached_info_logger = cache(logger.info)
|
|
14
17
|
__all__ = ["VispWriteL1Frame"]
|
|
@@ -54,7 +57,7 @@ class VispWriteL1Frame(WriteL1Frame):
|
|
|
54
57
|
"""
|
|
55
58
|
# Correct the headers for the number of map and scan steps per map due to potential observation aborts
|
|
56
59
|
header["VSPNMAPS"] = self.constants.num_map_scans
|
|
57
|
-
header[
|
|
60
|
+
header[VispMetadataKey.total_raster_steps] = self.constants.num_raster_steps
|
|
58
61
|
|
|
59
62
|
if stokes.upper() not in self.constants.stokes_params:
|
|
60
63
|
raise ValueError("The stokes parameter must be one of I, Q, U, V")
|
|
@@ -71,24 +74,27 @@ class VispWriteL1Frame(WriteL1Frame):
|
|
|
71
74
|
header[f"DTYPE{i}"] = "SPATIAL"
|
|
72
75
|
header[f"DPNAME{i}"] = "spatial along slit"
|
|
73
76
|
header[f"DWNAME{i}"] = "helioprojective latitude"
|
|
74
|
-
header[
|
|
77
|
+
if i < header["NAXIS"]:
|
|
78
|
+
header[f"CNAME{i}"] = "helioprojective latitude"
|
|
75
79
|
header[f"DUNIT{i}"] = header[f"CUNIT{i}"]
|
|
76
80
|
elif axis_type == "AWAV":
|
|
77
81
|
header[f"DNAXIS{i}"] = header[f"NAXIS{i}"]
|
|
78
82
|
header[f"DTYPE{i}"] = "SPECTRAL"
|
|
79
83
|
header[f"DPNAME{i}"] = "dispersion axis"
|
|
80
84
|
header[f"DWNAME{i}"] = "wavelength"
|
|
81
|
-
header[
|
|
85
|
+
if i < header["NAXIS"]:
|
|
86
|
+
header[f"CNAME{i}"] = "wavelength"
|
|
82
87
|
header[f"DUNIT{i}"] = header[f"CUNIT{i}"]
|
|
83
88
|
elif axis_type == "HPLN-TAN":
|
|
84
89
|
header[f"DNAXIS{i}"] = self.constants.num_raster_steps
|
|
85
90
|
header[f"DTYPE{i}"] = "SPATIAL"
|
|
86
91
|
header[f"DPNAME{i}"] = "raster scan step number"
|
|
87
92
|
header[f"DWNAME{i}"] = "helioprojective longitude"
|
|
88
|
-
header[
|
|
93
|
+
if i < header["NAXIS"]:
|
|
94
|
+
header[f"CNAME{i}"] = "helioprojective longitude"
|
|
89
95
|
header[f"DUNIT{i}"] = header[f"CUNIT{i}"]
|
|
90
96
|
# Current position in raster scan which counts from zero
|
|
91
|
-
header[f"DINDEX{i}"] = header[
|
|
97
|
+
header[f"DINDEX{i}"] = header[VispMetadataKey.raster_scan_step] + 1
|
|
92
98
|
else:
|
|
93
99
|
raise ValueError(
|
|
94
100
|
f"Unexpected axis type. Expected ['HPLT-TAN', 'AWAV', 'HPLN-TAN']. Got {axis_type}"
|
|
@@ -101,13 +107,14 @@ class VispWriteL1Frame(WriteL1Frame):
|
|
|
101
107
|
if self.constants.num_map_scans > 1:
|
|
102
108
|
cached_info_logger("Adding map scan dataset axis")
|
|
103
109
|
num_axis += 1
|
|
104
|
-
header[
|
|
105
|
-
|
|
106
|
-
|
|
110
|
+
header[f"DNAXIS{num_axis}"] = (
|
|
111
|
+
self.constants.num_map_scans
|
|
112
|
+
) # total number of raster scans in the dataset
|
|
107
113
|
header[f"DTYPE{num_axis}"] = "TEMPORAL"
|
|
108
114
|
header[f"DPNAME{num_axis}"] = "raster map repeat number"
|
|
109
115
|
header[f"DWNAME{num_axis}"] = "time"
|
|
110
|
-
header[
|
|
116
|
+
if num_axis < header["NAXIS"]:
|
|
117
|
+
header[f"CNAME{num_axis}"] = "time"
|
|
111
118
|
header[f"DUNIT{num_axis}"] = "s"
|
|
112
119
|
# Temporal position in dataset
|
|
113
120
|
header[f"DINDEX{num_axis}"] = header["VSPMAP"] # Current raster scan
|
|
@@ -120,7 +127,8 @@ class VispWriteL1Frame(WriteL1Frame):
|
|
|
120
127
|
header[f"DTYPE{num_axis}"] = "STOKES"
|
|
121
128
|
header[f"DPNAME{num_axis}"] = "polarization state"
|
|
122
129
|
header[f"DWNAME{num_axis}"] = "polarization state"
|
|
123
|
-
header[
|
|
130
|
+
if num_axis < header["NAXIS"]:
|
|
131
|
+
header[f"CNAME{num_axis}"] = "polarization state"
|
|
124
132
|
header[f"DUNIT{num_axis}"] = ""
|
|
125
133
|
# Stokes position in dataset - stokes axis goes from 1-4
|
|
126
134
|
header[f"DINDEX{num_axis}"] = self.constants.stokes_params.index(stokes.upper()) + 1
|
|
@@ -140,6 +148,9 @@ class VispWriteL1Frame(WriteL1Frame):
|
|
|
140
148
|
header["NBIN3"] = 1
|
|
141
149
|
header["NBIN"] = header["NBIN1"] * header["NBIN2"] * header["NBIN3"]
|
|
142
150
|
|
|
151
|
+
# Values don't have any units because they are relative to disk center
|
|
152
|
+
header["BUNIT"] = ("", "Values are relative to disk center. See calibration docs.")
|
|
153
|
+
|
|
143
154
|
return header
|
|
144
155
|
|
|
145
156
|
def calculate_date_end(self, header: fits.Header) -> str:
|
|
@@ -185,3 +196,20 @@ class VispWriteL1Frame(WriteL1Frame):
|
|
|
185
196
|
min=u.Quantity(minimum, unit=wavelength_unit),
|
|
186
197
|
max=u.Quantity(maximum, unit=wavelength_unit),
|
|
187
198
|
)
|
|
199
|
+
|
|
200
|
+
def add_timing_headers(self, header: fits.Header) -> fits.Header:
|
|
201
|
+
"""
|
|
202
|
+
Add timing headers to the FITS header.
|
|
203
|
+
|
|
204
|
+
This method adds or updates headers related to frame timings.
|
|
205
|
+
"""
|
|
206
|
+
# The source data is based on L0 data but L1 data takes L0 cadence * modstates to obtain.
|
|
207
|
+
# This causes both the cadence and the full exposure time to be num_modstates times longer.
|
|
208
|
+
header["CADENCE"] = self.constants.average_cadence * self.constants.num_modstates
|
|
209
|
+
header["CADMIN"] = self.constants.minimum_cadence * self.constants.num_modstates
|
|
210
|
+
header["CADMAX"] = self.constants.maximum_cadence * self.constants.num_modstates
|
|
211
|
+
header["CADVAR"] = self.constants.variance_cadence * self.constants.num_modstates
|
|
212
|
+
header[MetadataKey.fpa_exposure_time_ms] = (
|
|
213
|
+
header[MetadataKey.fpa_exposure_time_ms] * self.constants.num_modstates
|
|
214
|
+
)
|
|
215
|
+
return header
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from dataclasses import asdict
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
+
from dataclasses import field
|
|
4
5
|
from dataclasses import is_dataclass
|
|
5
6
|
from random import randint
|
|
7
|
+
from typing import Any
|
|
6
8
|
from typing import Callable
|
|
7
9
|
from typing import Type
|
|
8
10
|
|
|
@@ -12,10 +14,15 @@ from astropy.io import fits
|
|
|
12
14
|
from dkist_data_simulator.spec122 import Spec122Dataset
|
|
13
15
|
from dkist_header_validator.translator import sanitize_to_spec214_level1
|
|
14
16
|
from dkist_header_validator.translator import translate_spec122_to_spec214_l0
|
|
17
|
+
from dkist_processing_common.codecs.basemodel import basemodel_encoder
|
|
15
18
|
from dkist_processing_common.codecs.fits import fits_array_encoder
|
|
16
19
|
from dkist_processing_common.codecs.fits import fits_hdulist_encoder
|
|
20
|
+
from dkist_processing_common.models.input_dataset import InputDatasetPartDocumentList
|
|
17
21
|
from dkist_processing_common.tasks import WorkflowTaskBase
|
|
18
22
|
|
|
23
|
+
# Don't remove this; tests will break
|
|
24
|
+
from dkist_processing_common.tests.mock_metadata_store import fake_gql_client
|
|
25
|
+
|
|
19
26
|
from dkist_processing_visp.models.constants import VispConstants
|
|
20
27
|
from dkist_processing_visp.models.parameters import VispParameters
|
|
21
28
|
from dkist_processing_visp.models.tags import VispTag
|
|
@@ -38,6 +45,7 @@ def init_visp_constants_db():
|
|
|
38
45
|
|
|
39
46
|
@dataclass
|
|
40
47
|
class VispConstantsDb:
|
|
48
|
+
ARM_ID: int = 1
|
|
41
49
|
POLARIMETER_MODE: str = "observe_polarimetric"
|
|
42
50
|
OBS_IP_START_TIME: str = "2022-11-28T13:54:00"
|
|
43
51
|
NUM_MODSTATES: int = 10
|
|
@@ -61,8 +69,12 @@ class VispConstantsDb:
|
|
|
61
69
|
LAMP_READOUT_EXP_TIMES: tuple[float] = (200.0,)
|
|
62
70
|
SOLAR_READOUT_EXP_TIMES: tuple[float] = (2.0,)
|
|
63
71
|
OBSERVE_READOUT_EXP_TIMES: tuple[float] = (0.02,)
|
|
64
|
-
POLCAL_READOUT_EXP_TIMES: tuple[float] = ()
|
|
72
|
+
POLCAL_READOUT_EXP_TIMES: tuple[float] = (0.02,)
|
|
65
73
|
SPECTRAL_LINE: str = "VISP Ca II H"
|
|
74
|
+
INCIDENT_LIGHT_ANGLE_DEG: float = 73.22
|
|
75
|
+
REFLECTED_LIGHT_ANGLE_DEG: float = 64.92
|
|
76
|
+
GRATING_CONSTANT_INVERSE_MM: float = 316.0
|
|
77
|
+
SOLAR_GAIN_IP_START_TIME: str = "2025-09-24T20:00:00"
|
|
66
78
|
STOKES_PARAMS: tuple[str] = (
|
|
67
79
|
"I",
|
|
68
80
|
"Q",
|
|
@@ -81,6 +93,7 @@ class VispConstantsDb:
|
|
|
81
93
|
AXIS_1_TYPE: str = "HPLT-TAN"
|
|
82
94
|
AXIS_2_TYPE: str = "AWAV"
|
|
83
95
|
AXIS_3_TYPE: str = "HPLN-TAN"
|
|
96
|
+
RETARDER_NAME: str = "SiO2 OC"
|
|
84
97
|
|
|
85
98
|
|
|
86
99
|
@pytest.fixture()
|
|
@@ -124,19 +137,59 @@ class VispInputDatasetParameterValues:
|
|
|
124
137
|
visp_geo_upsample_factor: float = 10.0
|
|
125
138
|
visp_geo_max_shift: float = 40.0
|
|
126
139
|
visp_geo_poly_fit_order: int = 3
|
|
127
|
-
|
|
128
|
-
|
|
140
|
+
visp_geo_zone_prominence: WavelengthParameter = WavelengthParameter(values=(0.2, 0.2, 0.3, 0.2))
|
|
141
|
+
visp_geo_zone_width: WavelengthParameter = WavelengthParameter(values=(7, 2, 3, 2))
|
|
142
|
+
visp_geo_zone_bg_order: WavelengthParameter = WavelengthParameter(values=(21, 22, 11, 22))
|
|
143
|
+
visp_geo_zone_normalization_percentile: WavelengthParameter = WavelengthParameter(
|
|
144
|
+
values=(90, 99, 90, 90)
|
|
145
|
+
)
|
|
146
|
+
visp_geo_zone_rel_height: float = 0.97
|
|
147
|
+
visp_solar_spatial_median_filter_width_px: WavelengthParameter = WavelengthParameter(
|
|
148
|
+
values=(250, 250, 250, 250)
|
|
129
149
|
)
|
|
130
150
|
visp_solar_characteristic_spatial_normalization_percentile: float = 90.0
|
|
131
|
-
|
|
132
|
-
|
|
151
|
+
visp_solar_vignette_initial_continuum_poly_fit_order: int = 6
|
|
152
|
+
visp_solar_vignette_crval_bounds_px: float = 7
|
|
153
|
+
visp_solar_vignette_dispersion_bounds_fraction: float = 0.02
|
|
154
|
+
visp_solar_vignette_wavecal_fit_kwargs: dict[str, Any] = field(
|
|
155
|
+
default_factory=lambda: {
|
|
156
|
+
"method": "differential_evolution",
|
|
157
|
+
"init": "halton",
|
|
158
|
+
"popsize": 1,
|
|
159
|
+
"tol": 1e-10,
|
|
160
|
+
}
|
|
133
161
|
)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
162
|
+
visp_solar_vignette_spectral_poly_fit_order: int = 12
|
|
163
|
+
visp_solar_vignette_min_samples: float = 0.9
|
|
164
|
+
visp_wavecal_camera_lens_parameters_1: tuple[float, float, float] = (
|
|
165
|
+
0.7613,
|
|
166
|
+
1.720e-4,
|
|
167
|
+
-8.139e-8,
|
|
168
|
+
)
|
|
169
|
+
visp_wavecal_camera_lens_parameters_2: tuple[float, float, float] = (
|
|
170
|
+
0.9512,
|
|
171
|
+
2.141e-4,
|
|
172
|
+
-1.014e-7,
|
|
173
|
+
)
|
|
174
|
+
visp_wavecal_camera_lens_parameters_3: tuple[float, float, float] = (
|
|
175
|
+
0.1153e1,
|
|
176
|
+
2.595e-4,
|
|
177
|
+
-1.230e-7,
|
|
178
|
+
)
|
|
179
|
+
visp_wavecal_pixel_pitch_micron_per_pix: float = 6.5
|
|
180
|
+
visp_wavecal_atlas_download_config: dict[str, str] = field(
|
|
181
|
+
default_factory=lambda: {
|
|
182
|
+
"base_url": "doi:10.5281/zenodo.14646787/",
|
|
183
|
+
"telluric_reference_atlas_file_name": "telluric_reference_atlas.npy",
|
|
184
|
+
"telluric_reference_atlas_hash_id": "md5:8db5e12508b293bca3495d81a0747447",
|
|
185
|
+
"solar_reference_atlas_file_name": "solar_reference_atlas.npy",
|
|
186
|
+
"solar_reference_atlas_hash_id": "md5:84ab4c50689ef235fe5ed4f7ee905ca0",
|
|
187
|
+
}
|
|
138
188
|
)
|
|
139
|
-
|
|
189
|
+
visp_wavecal_init_crval_guess_normalization_percentile: float = 95
|
|
190
|
+
visp_wavecal_init_resolving_power: int = 150000
|
|
191
|
+
visp_wavecal_init_straylight_fraction: float = 0.2
|
|
192
|
+
visp_wavecal_init_opacity_factor: float = 5.0
|
|
140
193
|
visp_polcal_spatial_median_filter_width_px: int = 10
|
|
141
194
|
visp_polcal_num_spatial_bins: int = 10
|
|
142
195
|
visp_polcal_demod_spatial_smooth_fit_order: int = 17
|
|
@@ -144,7 +197,6 @@ class VispInputDatasetParameterValues:
|
|
|
144
197
|
visp_polcal_demod_upsample_order: int = 3
|
|
145
198
|
visp_pac_remove_linear_I_trend: bool = True
|
|
146
199
|
visp_pac_fit_mode: str = "use_M12_I_sys_per_step"
|
|
147
|
-
visp_pac_init_set: str = "OCCal_VIS"
|
|
148
200
|
|
|
149
201
|
|
|
150
202
|
@pytest.fixture(scope="session")
|
|
@@ -157,11 +209,37 @@ def testing_obs_ip_start_time() -> str:
|
|
|
157
209
|
return "1946-11-20T12:34:56"
|
|
158
210
|
|
|
159
211
|
|
|
212
|
+
@pytest.fixture(scope="session")
|
|
213
|
+
def testing_grating_constant() -> float:
|
|
214
|
+
# Just make it different than the defaults in header_models.py
|
|
215
|
+
return 317.2
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
@pytest.fixture(scope="session")
|
|
219
|
+
def testing_grating_angle() -> float:
|
|
220
|
+
return -43.2
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
@pytest.fixture(scope="session")
|
|
224
|
+
def testing_arm_position() -> float:
|
|
225
|
+
return -5.3
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
@pytest.fixture(scope="session")
|
|
229
|
+
def testing_solar_ip_start_time() -> str:
|
|
230
|
+
return "1946-11-21T12:34:56"
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
@pytest.fixture(scope="session")
|
|
234
|
+
def testing_arm_id() -> int:
|
|
235
|
+
return 2
|
|
236
|
+
|
|
237
|
+
|
|
160
238
|
@pytest.fixture(scope="session")
|
|
161
239
|
def input_dataset_document_simple_parameters_part():
|
|
162
240
|
"""Convert a dataclass of parameterValues into an actual input dataset parameters part."""
|
|
163
241
|
|
|
164
|
-
def
|
|
242
|
+
def make_input_dataset_parameters_part(parameter_values: dataclass):
|
|
165
243
|
parameters_list = []
|
|
166
244
|
value_id = randint(1000, 2000)
|
|
167
245
|
for pn, pv in asdict(parameter_values).items():
|
|
@@ -178,35 +256,42 @@ def input_dataset_document_simple_parameters_part():
|
|
|
178
256
|
parameters_list.append(parameter)
|
|
179
257
|
return parameters_list
|
|
180
258
|
|
|
181
|
-
return
|
|
259
|
+
return make_input_dataset_parameters_part
|
|
182
260
|
|
|
183
261
|
|
|
184
262
|
@pytest.fixture(scope="session")
|
|
185
263
|
def assign_input_dataset_doc_to_task(
|
|
186
|
-
input_dataset_document_simple_parameters_part,
|
|
264
|
+
input_dataset_document_simple_parameters_part,
|
|
265
|
+
testing_obs_ip_start_time,
|
|
266
|
+
testing_wavelength,
|
|
267
|
+
testing_arm_id,
|
|
187
268
|
):
|
|
188
269
|
def update_task(
|
|
189
|
-
task,
|
|
270
|
+
task: WorkflowTaskBase,
|
|
190
271
|
parameter_values,
|
|
191
272
|
parameter_class=VispParameters,
|
|
192
273
|
obs_ip_start_time=testing_obs_ip_start_time,
|
|
274
|
+
arm_id=testing_arm_id,
|
|
193
275
|
):
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
276
|
+
task.write(
|
|
277
|
+
data=InputDatasetPartDocumentList(
|
|
278
|
+
doc_list=input_dataset_document_simple_parameters_part(parameter_values)
|
|
279
|
+
),
|
|
280
|
+
tags=VispTag.input_dataset_parameters(),
|
|
281
|
+
encoder=basemodel_encoder,
|
|
282
|
+
)
|
|
198
283
|
task.parameters = parameter_class(
|
|
199
|
-
task.
|
|
284
|
+
scratch=task.scratch,
|
|
200
285
|
obs_ip_start_time=obs_ip_start_time,
|
|
201
286
|
wavelength=testing_wavelength,
|
|
287
|
+
arm_id=str(arm_id),
|
|
202
288
|
)
|
|
203
289
|
|
|
204
290
|
return update_task
|
|
205
291
|
|
|
206
292
|
|
|
207
293
|
def make_random_data(frame: Spec122Dataset) -> np.ndarray:
|
|
208
|
-
|
|
209
|
-
data = np.random.random(shape)
|
|
294
|
+
data = np.random.random(frame.array_shape)
|
|
210
295
|
|
|
211
296
|
return data
|
|
212
297
|
|
|
@@ -338,28 +423,14 @@ def write_intermediate_background_to_task(
|
|
|
338
423
|
)
|
|
339
424
|
|
|
340
425
|
|
|
341
|
-
def write_intermediate_lamp_to_task(
|
|
342
|
-
task, *, lamp_signal: float, beam: int, modstate: int, data_shape: tuple[int, int]
|
|
343
|
-
):
|
|
344
|
-
lamp_array = np.ones(data_shape) * lamp_signal
|
|
345
|
-
task.write(
|
|
346
|
-
data=lamp_array,
|
|
347
|
-
tags=[
|
|
348
|
-
VispTag.intermediate_frame(beam=beam, modstate=modstate),
|
|
349
|
-
VispTag.task_lamp_gain(),
|
|
350
|
-
],
|
|
351
|
-
encoder=fits_array_encoder,
|
|
352
|
-
)
|
|
353
|
-
|
|
354
|
-
|
|
355
426
|
def write_intermediate_solar_to_task(
|
|
356
|
-
task, *, solar_signal: float, beam: int,
|
|
427
|
+
task, *, solar_signal: float, beam: int, data_shape: tuple[int, int]
|
|
357
428
|
):
|
|
358
429
|
solar_array = np.ones(data_shape) * solar_signal
|
|
359
430
|
task.write(
|
|
360
431
|
data=solar_array,
|
|
361
432
|
tags=[
|
|
362
|
-
VispTag.intermediate_frame(beam=beam
|
|
433
|
+
VispTag.intermediate_frame(beam=beam),
|
|
363
434
|
VispTag.task_solar_gain(),
|
|
364
435
|
],
|
|
365
436
|
encoder=fits_array_encoder,
|
|
@@ -409,19 +480,46 @@ def write_intermediate_geometric_to_task(
|
|
|
409
480
|
def write_dummy_intermediate_solar_cals_to_task(
|
|
410
481
|
task,
|
|
411
482
|
*,
|
|
412
|
-
num_modstates: int,
|
|
413
483
|
data_shape: tuple[int, int],
|
|
414
484
|
):
|
|
415
485
|
solar_signal = 1.0
|
|
416
486
|
for beam in [1, 2]:
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
487
|
+
write_intermediate_solar_to_task(
|
|
488
|
+
task=task,
|
|
489
|
+
solar_signal=solar_signal,
|
|
490
|
+
beam=beam,
|
|
491
|
+
data_shape=data_shape,
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
def write_intermediate_polcal_darks_to_task(
|
|
496
|
+
task, *, dark_signal: float, readout_exp_time: float, data_shape: tuple[int, int]
|
|
497
|
+
):
|
|
498
|
+
dark_cal = np.ones(data_shape) * dark_signal
|
|
499
|
+
# Need a dark for each beam
|
|
500
|
+
for beam in [1, 2]:
|
|
501
|
+
task.write(
|
|
502
|
+
data=dark_cal,
|
|
503
|
+
tags=VispTag.intermediate_frame_polcal_dark(
|
|
504
|
+
beam=beam, readout_exp_time=readout_exp_time
|
|
505
|
+
),
|
|
506
|
+
encoder=fits_array_encoder,
|
|
507
|
+
)
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
def write_intermediate_polcal_gains_to_task(
|
|
511
|
+
task, *, gain_signal: float, readout_exp_time: float, data_shape: tuple[int, int]
|
|
512
|
+
):
|
|
513
|
+
gain_cal = np.ones(data_shape) * gain_signal
|
|
514
|
+
# Need a dark for each beam
|
|
515
|
+
for beam in [1, 2]:
|
|
516
|
+
task.write(
|
|
517
|
+
data=gain_cal,
|
|
518
|
+
tags=VispTag.intermediate_frame_polcal_gain(
|
|
519
|
+
beam=beam, readout_exp_time=readout_exp_time
|
|
520
|
+
),
|
|
521
|
+
encoder=fits_array_encoder,
|
|
522
|
+
)
|
|
425
523
|
|
|
426
524
|
|
|
427
525
|
def tag_on_map_raster_stokes(frame: VispHeadersValidCalibratedFrames) -> list[str]:
|