From 28d48e8e5f7726b708ec3facd6c624d89d3dede5 Mon Sep 17 00:00:00 2001 From: Hugo Buddelmeijer Date: Wed, 28 Aug 2024 16:40:49 +0200 Subject: [PATCH 1/2] Add units to DataContainer table directly. Perhaps this could be a first step to removing the units for tables from meta? --- scopesim/effects/data_container.py | 32 +++++++++++++++++++ scopesim/effects/detector_list.py | 19 +++++++---- .../tests/tests_optics/test_DataContainer.py | 10 ++++++ 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/scopesim/effects/data_container.py b/scopesim/effects/data_container.py index f2c48281..249426e0 100644 --- a/scopesim/effects/data_container.py +++ b/scopesim/effects/data_container.py @@ -120,6 +120,38 @@ def __init__(self, filename=None, table=None, array_dict=None, cmds=None, if array_dict is not None: self._from_arrays(array_dict) + # Get units as they are given in the kworgs. + unit_dict_kwargs = { + k: v + for k, v in kwargs.items() + if k.endswith("_unit") + } + + # Collect the units from the table. self.meta should contain both + # kwargs and headers from the file at this point. + unit_dict = { + k: v + for k, v in self.meta.items() + if k.endswith("_unit") + } + + # Verify that any units given in the kwargs + # are the same as those given in the table. + for k, v_kwargs in unit_dict_kwargs.items(): + v_table = unit_dict.get(k, v_kwargs) + if v_kwargs != v_table: + raise ValueError(f"Column {k} has unit {v_table} in table, but {v_kwargs} in kwargs") + + # Add units from kwargs if they are given. + if self.table: + for column in self.table.columns.values(): + key_unit = f"{column.name}_unit" + if key_unit not in unit_dict: + continue + unit_kwargs = unit_dict[key_unit] + if column.unit is None: + column.unit = unit_kwargs + def _from_table(self, table): self.table = table self.headers += [table.meta] diff --git a/scopesim/effects/detector_list.py b/scopesim/effects/detector_list.py index 06cb3af4..65c98616 100644 --- a/scopesim/effects/detector_list.py +++ b/scopesim/effects/detector_list.py @@ -344,10 +344,15 @@ def __init__(self, pixel_size, x, y, width, height=None, angle=0, gain=1, "image_plane_id": 0} params.update(kwargs) - tbl = Table(data=[[0], [x], [y], [width], [height], - [angle], [gain], [pixel_size]], - names=["id", "x_cen", "y_cen", "x_size", "y_size", - "angle", "gain", "pixel_size"]) - tbl.meta.update(params) - - super().__init__(table=tbl, **params) + array_dict = { + "id": [0], + "x_cen": [x], + "y_cen": [y], + "x_size": [width], + "y_size": [height], + "angle": [angle], + "gain": [gain], + "pixel_size": [pixel_size], + } + + super().__init__(array_dict=array_dict, **params) diff --git a/scopesim/tests/tests_optics/test_DataContainer.py b/scopesim/tests/tests_optics/test_DataContainer.py index 98f3df41..2cc9ebbd 100644 --- a/scopesim/tests/tests_optics/test_DataContainer.py +++ b/scopesim/tests/tests_optics/test_DataContainer.py @@ -37,6 +37,16 @@ def test_initialised_with_ascii_input(self, data_files): dat = DataContainer(data_files[1]) assert isinstance(dat, DataContainer) assert dat.is_fits is False + assert dat.table.colnames == ['wavelength', 'transmission'] + column = dat.table['wavelength'] + assert column.unit == "um" + + def test_raises_wrong_units(self, data_files): + with pytest.raises(ValueError): + _ = DataContainer( + data_files[1], + wavelength_unit="m", + ) def test_initialised_with_arrays_dict_input(self): array_dict = {"wavelength": np.linspace(1, 2, 11)*u.um, From f29502a94632954c477147381e2a69aacbb0caf3 Mon Sep 17 00:00:00 2001 From: Hugo Buddelmeijer Date: Wed, 28 Aug 2024 17:19:39 +0200 Subject: [PATCH 2/2] Remove QTable for now.. But maybe we should always use QTables instead --- scopesim/effects/ter_curves_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scopesim/effects/ter_curves_utils.py b/scopesim/effects/ter_curves_utils.py index 92719a0f..56802631 100644 --- a/scopesim/effects/ter_curves_utils.py +++ b/scopesim/effects/ter_curves_utils.py @@ -133,7 +133,7 @@ def download_svo_filter(filter_name, return_style="synphot"): if return_style == "synphot": return SpectralElement(Empirical1D, points=wave, lookup_table=trans) if return_style == "table": - filt = QTable(data=[wave, trans], names=["wavelength", "transmission"]) + filt = Table(data=[wave, trans], names=["wavelength", "transmission"]) filt.meta["wavelength_unit"] = str(wave.unit) filt.meta["votable_meta"] = tbl_meta # Don't pollute actual meta... return filt