From 13ac4dbf58a9dcc18128bb11512cc5de2c7b8102 Mon Sep 17 00:00:00 2001 From: Kieran Leschinski Date: Tue, 23 Jan 2024 21:10:03 +0100 Subject: [PATCH 01/10] from_currsys update to recurring bang-strings --- scopesim/utils.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index c655d418..1bbe0e3c 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -863,11 +863,18 @@ def from_currsys(item): if isinstance(item, str) and len(item) and item.startswith("!"): if item in rc.__currsys__: item = rc.__currsys__[item] + if isinstance(item, str) and item.startswith("!"): + item = from_currsys(item) else: raise ValueError(f"{item} was not found in rc.__currsys__") - if isinstance(item, str) and item.lower() == "none": - item = None + if isinstance(item, str): + if item.lower() == "none": + item = None + try: + item = float(item) + except: + pass return item From 7d8e3e68a3b2d3a24324c3ea01718e40a9198eea Mon Sep 17 00:00:00 2001 From: Kieran Leschinski Date: Tue, 23 Jan 2024 21:20:43 +0100 Subject: [PATCH 02/10] minor bug fix for displaying transmissions from optics_manager.surface_table --- scopesim/effects/effects_utils.py | 2 +- scopesim/effects/surface_list.py | 4 ++-- scopesim/effects/ter_curves.py | 22 ++++++++++++++++++++-- scopesim/optics/optics_manager.py | 18 ++++++++++++++---- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/scopesim/effects/effects_utils.py b/scopesim/effects/effects_utils.py index c3c680c2..2c1280fb 100644 --- a/scopesim/effects/effects_utils.py +++ b/scopesim/effects/effects_utils.py @@ -41,7 +41,7 @@ def combine_surface_effects(surface_effects): surflist_list = [eff for eff in surface_effects if isinstance(eff, efs.SurfaceList)] surf_list = [eff for eff in surface_effects - if isinstance(eff, (efs.TERCurve, efs.FilterWheel)) + if isinstance(eff, (efs.TERCurve, efs.FilterWheelBase)) and not isinstance(eff, efs.SurfaceList)] if not surflist_list: diff --git a/scopesim/effects/surface_list.py b/scopesim/effects/surface_list.py index deadcdc7..367c16b6 100644 --- a/scopesim/effects/surface_list.py +++ b/scopesim/effects/surface_list.py @@ -3,7 +3,7 @@ import numpy as np from astropy import units as u -from .ter_curves import TERCurve +from .ter_curves import TERCurve, FilterWheelBase from ..optics import radiometry_utils as rad_utils from ..optics.surface import PoorMansSurface from ..utils import quantify, from_currsys, figure_factory @@ -119,7 +119,7 @@ def is_empty(self): def add_surface(self, surface, name=None, position=-1, add_to_table=True): if name is None: name = surface.meta.get("name", "") - if isinstance(surface, TERCurve): + if isinstance(surface, (TERCurve, FilterWheelBase)): ter_meta = surface.meta surface = surface.surface surface.meta.update(ter_meta) diff --git a/scopesim/effects/ter_curves.py b/scopesim/effects/ter_curves.py index dbe56414..7e7fafc8 100644 --- a/scopesim/effects/ter_curves.py +++ b/scopesim/effects/ter_curves.py @@ -1,5 +1,5 @@ """Transmission, emissivity, reflection curves.""" - +import logging from collections.abc import Collection import numpy as np @@ -26,6 +26,9 @@ class TERCurve(Effect): """ Transmission, Emissivity, Reflection Curve. + note:: This is basically an ``Effect`` wrapper for the + ``SpectralSurface`` object + Must contain a wavelength column, and one or more of the following: ``transmission``, ``emissivity``, ``reflection``. Additionally, in the header there @@ -201,7 +204,12 @@ def plot(self, which="x", wavelength=None, *, axes=None, **kwargs): if wavelength is None: wunit = params["wave_unit"] # TODO: shouldn't need both, make sure they're equal - assert wunit == wave_unit + if wunit != wave_unit: + logger.warning(f"wavelength units in the meta dict of " + f"{self.meta.get('name')} are inconsistent: \n" + f"- wavelength_unit : {wave_unit} \n" + f"- wave_unit : {wunit}") + wave = np.arange(quantify(params["wave_min"], wunit).value, quantify(params["wave_max"], wunit).value, quantify(params["wave_bin"], wunit).value) @@ -213,6 +221,8 @@ def plot(self, which="x", wavelength=None, *, axes=None, **kwargs): abbrs = {"t": "transmission", "e": "emission", "r": "reflection", "x": "throughput"} + if not isinstance(axes, list): + axes = [axes] for ter, ax in zip(which, axes): y_name = abbrs.get(ter, "throughput") y = getattr(self.surface, y_name) @@ -581,6 +591,14 @@ def apply_to(self, obj, **kwargs): """Use apply_to of current filter.""" return self.current_filter.apply_to(obj, **kwargs) + @property + def surface(self): + return self.current_filter.surface + + @property + def throughput(self): + return self.current_filter.throughput + def fov_grid(self, which="waveset", **kwargs): return self.current_filter.fov_grid(which=which, **kwargs) diff --git a/scopesim/optics/optics_manager.py b/scopesim/optics/optics_manager.py index 3b995cc9..9ecc20d8 100644 --- a/scopesim/optics/optics_manager.py +++ b/scopesim/optics/optics_manager.py @@ -237,10 +237,20 @@ def fov_setup_effects(self): @property def surfaces_table(self): """Get combined surface table from effects with z_order = 100...199.""" - if self._surfaces_table is None: - surface_like_effects = self.get_z_order_effects(100) - self._surfaces_table = combine_surface_effects(surface_like_effects) - return self._surfaces_table + from copy import deepcopy + sle_list = self.get_z_order_effects(100) + sle_list_copy = [] + for eff in sle_list: + if isinstance(eff, efs.SurfaceList): + eff_copy = deepcopy(eff) + eff_copy.table = from_currsys(eff.table) + else: + # Avoid infinite recursion in Wheel effects (filter, adc) + eff_copy = eff + sle_list_copy += [eff_copy] + + comb_table = combine_surface_effects(sle_list_copy) + return comb_table @property def all_effects(self): From 1981504f0ea4fab5c505e0dbc568b5e466fa6da0 Mon Sep 17 00:00:00 2001 From: teutoburg <73600109+teutoburg@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:44:41 +0100 Subject: [PATCH 03/10] Remove unused import --- scopesim/effects/ter_curves.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scopesim/effects/ter_curves.py b/scopesim/effects/ter_curves.py index 7e7fafc8..44a4814e 100644 --- a/scopesim/effects/ter_curves.py +++ b/scopesim/effects/ter_curves.py @@ -1,5 +1,4 @@ """Transmission, emissivity, reflection curves.""" -import logging from collections.abc import Collection import numpy as np From df3ba0236fe33e0a8041b473a2a98c502da26a67 Mon Sep 17 00:00:00 2001 From: teutoburg <73600109+teutoburg@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:45:11 +0100 Subject: [PATCH 04/10] No bare except --- scopesim/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index 1bbe0e3c..7923356b 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -873,7 +873,7 @@ def from_currsys(item): item = None try: item = float(item) - except: + except TypeError: pass return item From 64752950a2c4455dcc87efc0b30eadd81468c468 Mon Sep 17 00:00:00 2001 From: teutoburg <73600109+teutoburg@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:51:51 +0100 Subject: [PATCH 05/10] Could also be ValueError my bad --- scopesim/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scopesim/utils.py b/scopesim/utils.py index 7923356b..b27ba880 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -873,7 +873,7 @@ def from_currsys(item): item = None try: item = float(item) - except TypeError: + except (TypeError, ValueError): pass return item From 09a2adcdb25b93fa5856ec933e90df529a6fd3da Mon Sep 17 00:00:00 2001 From: Kieran Leschinski Date: Tue, 30 Jan 2024 11:17:07 +0100 Subject: [PATCH 06/10] Update scopesim/optics/optics_manager.py Co-authored-by: teutoburg <73600109+teutoburg@users.noreply.github.com> --- scopesim/optics/optics_manager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scopesim/optics/optics_manager.py b/scopesim/optics/optics_manager.py index 9ecc20d8..acdc7130 100644 --- a/scopesim/optics/optics_manager.py +++ b/scopesim/optics/optics_manager.py @@ -247,7 +247,7 @@ def surfaces_table(self): else: # Avoid infinite recursion in Wheel effects (filter, adc) eff_copy = eff - sle_list_copy += [eff_copy] + sle_list_copy.append(eff_copy) comb_table = combine_surface_effects(sle_list_copy) return comb_table From 3690d25967ad70d8c0ab52e1532abe1dedc767e4 Mon Sep 17 00:00:00 2001 From: Kieran Leschinski Date: Tue, 30 Jan 2024 11:19:43 +0100 Subject: [PATCH 07/10] Update scopesim/effects/ter_curves.py Co-authored-by: teutoburg <73600109+teutoburg@users.noreply.github.com> --- scopesim/effects/ter_curves.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scopesim/effects/ter_curves.py b/scopesim/effects/ter_curves.py index 44a4814e..f3dd7033 100644 --- a/scopesim/effects/ter_curves.py +++ b/scopesim/effects/ter_curves.py @@ -204,10 +204,12 @@ def plot(self, which="x", wavelength=None, *, axes=None, **kwargs): wunit = params["wave_unit"] # TODO: shouldn't need both, make sure they're equal if wunit != wave_unit: - logger.warning(f"wavelength units in the meta dict of " - f"{self.meta.get('name')} are inconsistent: \n" - f"- wavelength_unit : {wave_unit} \n" - f"- wave_unit : {wunit}") + logger.warning("wavelength units in the meta dict of " + "%s are inconsistent:\n" + "- wavelength_unit : %s\n" + "- wave_unit : %s", + {self.meta.get("name")}, + wave_unit, wunit) wave = np.arange(quantify(params["wave_min"], wunit).value, quantify(params["wave_max"], wunit).value, From 48adf836a0016e28a7e4e796e27b32fc7fa6309a Mon Sep 17 00:00:00 2001 From: Kieran Leschinski Date: Tue, 30 Jan 2024 20:42:55 +0100 Subject: [PATCH 08/10] added unit test for multi-level bang-strings --- scopesim/__init__.py | 5 ++++- scopesim/effects/ter_curves.py | 5 +++-- scopesim/tests/test_utils_functions.py | 10 ++++++++++ scopesim/version.py | 5 ++++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/scopesim/__init__.py b/scopesim/__init__.py index 97946132..16fb1246 100644 --- a/scopesim/__init__.py +++ b/scopesim/__init__.py @@ -82,4 +82,7 @@ # VERSION INFORMATION # ############################################################################### -__version__ = metadata.version(__package__) +try: + __version__ = metadata.version(__package__) +except: + version = 0.8 diff --git a/scopesim/effects/ter_curves.py b/scopesim/effects/ter_curves.py index 44a4814e..e97b480a 100644 --- a/scopesim/effects/ter_curves.py +++ b/scopesim/effects/ter_curves.py @@ -1,5 +1,5 @@ """Transmission, emissivity, reflection curves.""" -from collections.abc import Collection +from collections.abc import Collection, Iterable import numpy as np import skycalc_ipy @@ -220,7 +220,8 @@ def plot(self, which="x", wavelength=None, *, axes=None, **kwargs): abbrs = {"t": "transmission", "e": "emission", "r": "reflection", "x": "throughput"} - if not isinstance(axes, list): + + if not isinstance(axes, Iterable): axes = [axes] for ter, ax in zip(which, axes): y_name = abbrs.get(ter, "throughput") diff --git a/scopesim/tests/test_utils_functions.py b/scopesim/tests/test_utils_functions.py index bcc639fd..6872a7f1 100644 --- a/scopesim/tests/test_utils_functions.py +++ b/scopesim/tests/test_utils_functions.py @@ -185,6 +185,16 @@ def test_converts_numpy_array(self): def test_converts_dict(self): assert utils.from_currsys({"seed": "!SIM.random.seed"})["seed"] is None + def test_converts_layered_bang_strings(self): + old = rc.__currsys__["!SIM.sub_pixel.flag"] + rc.__currsys__["!SIM.sub_pixel.flag"] = "!SIM.sub_pixel.fraction" + + result = utils.from_currsys("!SIM.sub_pixel.flag") + assert not isinstance(result, str) + assert result == 1 + + rc.__currsys__["!SIM.sub_pixel.flag"] = old + def test_converts_astropy_table(self): tbl = Table(data=[["!SIM.random.seed"]*2, ["!SIM.random.seed"]*2], names=["seeds", "seeds2"]) diff --git a/scopesim/version.py b/scopesim/version.py index 1aa1954b..c3a8644b 100644 --- a/scopesim/version.py +++ b/scopesim/version.py @@ -1,2 +1,5 @@ from importlib import metadata -version = metadata.version(__package__) +try: + version = metadata.version(__package__) +except: + version = 0.8 From d266d0005aede14a708cf4a822517d0e48927460 Mon Sep 17 00:00:00 2001 From: Kieran Leschinski Date: Wed, 31 Jan 2024 10:34:55 +0100 Subject: [PATCH 09/10] added test to increase code cov --- scopesim/tests/test_utils_functions.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scopesim/tests/test_utils_functions.py b/scopesim/tests/test_utils_functions.py index 6872a7f1..adb994f2 100644 --- a/scopesim/tests/test_utils_functions.py +++ b/scopesim/tests/test_utils_functions.py @@ -200,6 +200,15 @@ def test_converts_astropy_table(self): names=["seeds", "seeds2"]) assert utils.from_currsys(tbl["seeds2"][1]) is None + def test_converts_string_numericals_to_floats(self): + old = rc.__currsys__["!SIM.sub_pixel.fraction"] + rc.__currsys__["!SIM.sub_pixel.fraction"] = "1e0" + + result = utils.from_currsys("!SIM.sub_pixel.fraction") + assert isinstance(result, float) + assert result == 1 + + rc.__currsys__["!SIM.sub_pixel.flag"] = old # load_example_optical_train modifies __currsys__! From 7ba43343507b8ff50e23229ae622b534a5bdb2cf Mon Sep 17 00:00:00 2001 From: teutoburg Date: Wed, 31 Jan 2024 12:14:02 +0100 Subject: [PATCH 10/10] Fix utils tests, fallback version --- scopesim/__init__.py | 4 ++-- scopesim/tests/test_utils_functions.py | 26 ++++++++++---------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/scopesim/__init__.py b/scopesim/__init__.py index b30d4ec1..334da299 100644 --- a/scopesim/__init__.py +++ b/scopesim/__init__.py @@ -65,5 +65,5 @@ try: __version__ = metadata.version(__package__) -except: - version = 0.8 +except metadata.PackageNotFoundError: + __version__ = "undetermined" diff --git a/scopesim/tests/test_utils_functions.py b/scopesim/tests/test_utils_functions.py index adb994f2..6f5ff8bb 100644 --- a/scopesim/tests/test_utils_functions.py +++ b/scopesim/tests/test_utils_functions.py @@ -186,14 +186,11 @@ def test_converts_dict(self): assert utils.from_currsys({"seed": "!SIM.random.seed"})["seed"] is None def test_converts_layered_bang_strings(self): - old = rc.__currsys__["!SIM.sub_pixel.flag"] - rc.__currsys__["!SIM.sub_pixel.flag"] = "!SIM.sub_pixel.fraction" - - result = utils.from_currsys("!SIM.sub_pixel.flag") - assert not isinstance(result, str) - assert result == 1 - - rc.__currsys__["!SIM.sub_pixel.flag"] = old + patched = {"!SIM.sub_pixel.flag": "!SIM.sub_pixel.fraction"} + with patch.dict("scopesim.rc.__currsys__", patched): + result = utils.from_currsys("!SIM.sub_pixel.flag") + assert not isinstance(result, str) + assert result == 1 def test_converts_astropy_table(self): tbl = Table(data=[["!SIM.random.seed"]*2, ["!SIM.random.seed"]*2], @@ -201,14 +198,11 @@ def test_converts_astropy_table(self): assert utils.from_currsys(tbl["seeds2"][1]) is None def test_converts_string_numericals_to_floats(self): - old = rc.__currsys__["!SIM.sub_pixel.fraction"] - rc.__currsys__["!SIM.sub_pixel.fraction"] = "1e0" - - result = utils.from_currsys("!SIM.sub_pixel.fraction") - assert isinstance(result, float) - assert result == 1 - - rc.__currsys__["!SIM.sub_pixel.flag"] = old + patched = {"!SIM.sub_pixel.fraction": "1e0"} + with patch.dict("scopesim.rc.__currsys__", patched): + result = utils.from_currsys("!SIM.sub_pixel.fraction") + assert isinstance(result, float) + assert result == 1 # load_example_optical_train modifies __currsys__!