dkist-processing-common 10.8.1__py3-none-any.whl → 10.8.2__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.
@@ -295,10 +295,14 @@ class WriteL1Frame(WorkflowTaskBase, MetadataStoreMixin, ABC):
295
295
  header["SOLARRAD"] = self.calculate_solar_angular_radius(obstime=obstime)
296
296
  header["SPECSYS"] = "TOPOCENT" # no wavelength correction made due to doppler velocity
297
297
  header["VELOSYS"] = 0.0 # no wavelength correction made due to doppler velocity
298
- header["WAVEBAND"] = get_closest_spectral_line(wavelength=header["LINEWAV"] * u.nm).name
299
298
  wavelength_range = self.get_wavelength_range(header=header)
300
299
  header["WAVEMIN"] = wavelength_range.min.to_value(u.nm)
301
300
  header["WAVEMAX"] = wavelength_range.max.to_value(u.nm)
301
+ waveband: str | None = self.get_waveband(
302
+ wavelength=header["LINEWAV"] * u.nm, wavelength_range=wavelength_range
303
+ )
304
+ if waveband:
305
+ header["WAVEBAND"] = waveband
302
306
  return header
303
307
 
304
308
  def l1_filename(self, header: fits.Header, stokes: Literal["I", "Q", "U", "V"]):
@@ -515,3 +519,18 @@ class WriteL1Frame(WorkflowTaskBase, MetadataStoreMixin, ABC):
515
519
  if header.get("AO_LOCK") is not True:
516
520
  header.pop("ATMOS_R0", None)
517
521
  return header
522
+
523
+ @staticmethod
524
+ def get_waveband(wavelength: u.Quantity, wavelength_range: WavelengthRange) -> str | None:
525
+ """
526
+ Get the spectral line information of the closest spectral line to the wavelength argument.
527
+
528
+ If the spectral line rest wavelength in air does not fall in the wavelength range of the data,
529
+ do not populate the keyword.
530
+ """
531
+ print(wavelength_range)
532
+ closest_line = get_closest_spectral_line(wavelength=wavelength)
533
+ rest_wavelength = closest_line.rest_wavelength_in_air
534
+ if rest_wavelength < wavelength_range.min or rest_wavelength > wavelength_range.max:
535
+ return None
536
+ return closest_line.name
@@ -101,6 +101,12 @@ class CompleteWriteL1Frame(WriteL1Frame):
101
101
  return WavelengthRange(min=1075.0 * u.nm, max=1085.0 * u.nm)
102
102
 
103
103
 
104
+ class CompleteWriteL1FrameWithEmptyWaveband(CompleteWriteL1Frame):
105
+ def get_wavelength_range(self, header: fits.Header) -> WavelengthRange:
106
+ # Return an empty range to test the empty waveband case
107
+ return WavelengthRange(min=10000.0 * u.nm, max=10050.0 * u.nm)
108
+
109
+
104
110
  @dataclass
105
111
  class FakeConstantDb:
106
112
  INSTRUMENT: str = "TEST"
@@ -154,6 +160,44 @@ def write_l1_task(request, recipe_run_id, tmp_path):
154
160
  task._purge()
155
161
 
156
162
 
163
+ @pytest.fixture(
164
+ scope="function",
165
+ params=[
166
+ pytest.param((1, "complete_common_header"), id="Intensity"),
167
+ pytest.param((4, "complete_polarimetric_header"), id="Polarimetric"),
168
+ ],
169
+ )
170
+ def write_l1_task_with_empty_waveband(recipe_run_id, tmp_path, request):
171
+ with CompleteWriteL1FrameWithEmptyWaveband(
172
+ recipe_run_id=recipe_run_id,
173
+ workflow_name="workflow_name",
174
+ workflow_version="workflow_version",
175
+ ) as task:
176
+ task.scratch = WorkflowFileSystem(recipe_run_id=recipe_run_id, scratch_base_path=tmp_path)
177
+ num_of_stokes_params, header_fixture_name = request.param
178
+ header = request.getfixturevalue(header_fixture_name)
179
+ stokes_params = ["I", "Q", "U", "V"]
180
+ used_stokes_params = []
181
+ hdu = fits.PrimaryHDU(data=np.random.random(size=(1, 128, 128)) * 10, header=header)
182
+ hdu.header["IPTASK"] = "level0_only key to be removed"
183
+ hdul = fits.HDUList([hdu])
184
+ for i in range(num_of_stokes_params):
185
+ task.write(
186
+ data=hdul,
187
+ tags=[
188
+ Tag.calibrated(),
189
+ Tag.frame(),
190
+ Tag.stokes(stokes_params[i]),
191
+ Tag.dsps_repeat(i),
192
+ ],
193
+ encoder=fits_hdulist_encoder,
194
+ )
195
+ used_stokes_params.append(stokes_params[i])
196
+ task.constants._update(asdict(FakeConstantDb()))
197
+ yield task, used_stokes_params, header
198
+ task._purge()
199
+
200
+
157
201
  @pytest.fixture(
158
202
  scope="function",
159
203
  params=[
@@ -616,3 +660,67 @@ def test_check_r0_ao_lock(write_l1_task_no_data):
616
660
  with pytest.raises(KeyError, match="Keyword 'ATMOS_R0' not found"):
617
661
  invalid_r0 = header_after_check["ATMOS_R0"]
618
662
  assert header.get("AO_LOCK") != True
663
+
664
+
665
+ @pytest.mark.parametrize(
666
+ "wavelength, wavemin, wavemax, expected",
667
+ [
668
+ pytest.param(
669
+ 617,
670
+ 615,
671
+ 619,
672
+ "Fe I (617.33 nm)",
673
+ id="line_is_between_wavemin_and_wavemax_and_exists",
674
+ ),
675
+ pytest.param(
676
+ 700,
677
+ 698,
678
+ 702,
679
+ None,
680
+ id="line_is_between_wavemin_and_wavemax_and_does_not_exist",
681
+ ),
682
+ pytest.param(
683
+ 617,
684
+ 698,
685
+ 702,
686
+ None,
687
+ id="line_is_not_between_wavemin_and_wavemax_and_exists",
688
+ ),
689
+ ],
690
+ )
691
+ def test_get_waveband(write_l1_task, wavelength, wavemin, wavemax, expected):
692
+ """
693
+ :Given: an input wavelength contribution
694
+ :When: determining the waveband
695
+ :Then: the correct waveband is returned
696
+ """
697
+ wavelength_range = WavelengthRange(min=wavemin * u.nm, max=wavemax * u.nm)
698
+ task, _, _ = write_l1_task
699
+ waveband = task.get_waveband(wavelength=wavelength * u.nm, wavelength_range=wavelength_range)
700
+ assert waveband == expected
701
+
702
+
703
+ def test_empty_waveband(write_l1_task_with_empty_waveband, mocker):
704
+ """
705
+ :Given: a header converted to SPEC 214 L1 and a wavelength range that has no listed spectral lines
706
+ :When: checking the waveband key
707
+ :Then: it does not exist
708
+ """
709
+ mocker.patch(
710
+ "dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
711
+ )
712
+ mocker.patch(
713
+ "dkist_processing_common.tasks.write_l1.WriteL1Frame.version_from_module_name",
714
+ new_callable=Mock,
715
+ return_value="fake_version_number",
716
+ )
717
+
718
+ task, _, _ = write_l1_task_with_empty_waveband
719
+ task()
720
+ files = list(task.read(tags=[Tag.frame(), Tag.output()]))
721
+ for file in files:
722
+ header = fits.open(file)[1].header
723
+ assert header["WAVEMIN"] == 10000
724
+ assert header["WAVEMAX"] == 10050
725
+ with pytest.raises(KeyError):
726
+ header["WAVEBAND"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-processing-common
3
- Version: 10.8.1
3
+ Version: 10.8.2
4
4
  Summary: Common task classes used by the DKIST science data processing pipelines
5
5
  Author-email: NSO / AURA <dkistdc@nso.edu>
6
6
  License: BSD-3-Clause
@@ -58,7 +58,7 @@ dkist_processing_common/tasks/teardown.py,sha256=e4LKnphJDYDVDAez2tH7MxpZgCmxYsK
58
58
  dkist_processing_common/tasks/transfer_input_data.py,sha256=afEW0glpCFMZRj90nFtQo_4XOQ4CuoOh86jahP6a-a0,5548
59
59
  dkist_processing_common/tasks/trial_catalog.py,sha256=Y3DKstRfMS8nWWtJFMB0MUVPlZ1jWS_2jhJGMWwxy50,8748
60
60
  dkist_processing_common/tasks/trial_output_data.py,sha256=aI_aRuu0qVO8zFGrr_9baxx9i3jUEHZSmsmbO6ytlkE,6960
61
- dkist_processing_common/tasks/write_l1.py,sha256=8KQ5LWa15mmjcoN0EgyaeLJS2qxeAowU5MC8IEIt4l4,22695
61
+ dkist_processing_common/tasks/write_l1.py,sha256=vwNJs8gSzc0RPIfcpZ267L6pIJWdbPQ8ZmKR6hX1BIs,23498
62
62
  dkist_processing_common/tasks/mixin/__init__.py,sha256=-g-DQbU7m1bclJYuFe3Yh757V-35GIDTbstardKQ7nU,68
63
63
  dkist_processing_common/tasks/mixin/globus.py,sha256=QAV8VElxMAqxJ2KSB_bJaraceovYfjHXjOdocrTCkIA,6592
64
64
  dkist_processing_common/tasks/mixin/input_dataset.py,sha256=dkW5vf_QPgWedHO_Lf9GjBxr1QrUCKs6gIXufUTi7GE,6813
@@ -100,7 +100,7 @@ dkist_processing_common/tests/test_transfer_l1_output_data.py,sha256=27PifkyH3RZ
100
100
  dkist_processing_common/tests/test_trial_catalog.py,sha256=SZ-nyn0MXU9Lkg_94FbKER_cwiGoi06GYlzF_3AmvKg,6802
101
101
  dkist_processing_common/tests/test_trial_output_data.py,sha256=cBCj0kXyF5NEMzKh6zPVksdoXyE8ju1opJgWgjdcJWA,12790
102
102
  dkist_processing_common/tests/test_workflow_task_base.py,sha256=Z5aPW5LQtS0UWJiYho4X0r-2gPLfzpkmMwfmaoFLjMg,10517
103
- dkist_processing_common/tests/test_write_l1.py,sha256=xdPqIeS7brVUzDD0XmCVKc4N4QUbaUc0ENMFBwCYU2c,22203
103
+ dkist_processing_common/tests/test_write_l1.py,sha256=ahAdMg3QhE-gnV_UMhL_xne-H5nHHDVMOWrP1vonIQ0,25962
104
104
  docs/Makefile,sha256=qnlVz6PuBqE39NfHWuUnHhNEA-EFgT2-WJNNNy9ttfk,4598
105
105
  docs/changelog.rst,sha256=S2jPASsWlQxSlAPqdvNrYvhk9k3FcFWNXFNDYXBSjl4,120
106
106
  docs/conf.py,sha256=FkX575cqTqZGCcLAjg2MlvE8Buj1Vt3CpHNgZxG256E,1890
@@ -109,7 +109,7 @@ docs/landing_page.rst,sha256=aPAuXFhBx73lEZ59B6E6JXxkK0LlxzD0n-HXqHrfumQ,746
109
109
  docs/make.bat,sha256=mBAhtURwhQ7yc95pqwJzlhqBSvRknr1aqZ5s8NKvdKs,4513
110
110
  docs/requirements.txt,sha256=Kbl_X4c7RQZw035YTeNB63We6I7pvXFU4T0Uflp2yDY,29
111
111
  licenses/LICENSE.rst,sha256=piZaQplkzOMmH1NXg6QIdo9wwo9pPCoHkvm2-DmH76E,1462
112
- dkist_processing_common-10.8.1.dist-info/METADATA,sha256=8ErJWgpOSScbTNPpb6clo9dXRSkHlKzsTCasI4LS6fo,7147
113
- dkist_processing_common-10.8.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
114
- dkist_processing_common-10.8.1.dist-info/top_level.txt,sha256=LJhd1W-Vn90K8HnQDIE4r52YDpUjjMWDnllAWHBByW0,48
115
- dkist_processing_common-10.8.1.dist-info/RECORD,,
112
+ dkist_processing_common-10.8.2.dist-info/METADATA,sha256=8bbHCAylpH-0Ux_TMjUDNRySAFXKZHStbLWMYaQSKF8,7147
113
+ dkist_processing_common-10.8.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
114
+ dkist_processing_common-10.8.2.dist-info/top_level.txt,sha256=LJhd1W-Vn90K8HnQDIE4r52YDpUjjMWDnllAWHBByW0,48
115
+ dkist_processing_common-10.8.2.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5