diff --git a/scopesim/__init__.py b/scopesim/__init__.py index 96dc7daf..334da299 100644 --- a/scopesim/__init__.py +++ b/scopesim/__init__.py @@ -63,4 +63,7 @@ # VERSION INFORMATION # ############################################################################### -__version__ = metadata.version(__package__) +try: + __version__ = metadata.version(__package__) +except metadata.PackageNotFoundError: + __version__ = "undetermined" 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 95dfd042..c610b650 100644 --- a/scopesim/effects/surface_list.py +++ b/scopesim/effects/surface_list.py @@ -4,7 +4,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 @@ -122,7 +122,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 91b00298..276e64aa 100644 --- a/scopesim/effects/ter_curves.py +++ b/scopesim/effects/ter_curves.py @@ -1,7 +1,6 @@ """Transmission, emissivity, reflection curves.""" - import warnings -from collections.abc import Collection +from collections.abc import Collection, Iterable import numpy as np import skycalc_ipy @@ -27,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 @@ -202,7 +204,14 @@ 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("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, quantify(params["wave_bin"], wunit).value) @@ -214,6 +223,8 @@ def plot(self, which="x", wavelength=None, *, axes=None, **kwargs): abbrs = {"t": "transmission", "e": "emission", "r": "reflection", "x": "throughput"} + if not isinstance(axes, Iterable): + axes = [axes] for ter, ax in zip(which, axes): y_name = abbrs.get(ter, "throughput") y = getattr(self.surface, y_name) @@ -584,6 +595,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): warnings.warn("The fov_grid method is deprecated and will be removed " "in a future release.", DeprecationWarning, stacklevel=2) diff --git a/scopesim/optics/optics_manager.py b/scopesim/optics/optics_manager.py index 3b995cc9..acdc7130 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.append(eff_copy) + + comb_table = combine_surface_effects(sle_list_copy) + return comb_table @property def all_effects(self): diff --git a/scopesim/tests/test_utils_functions.py b/scopesim/tests/test_utils_functions.py index bcc639fd..6f5ff8bb 100644 --- a/scopesim/tests/test_utils_functions.py +++ b/scopesim/tests/test_utils_functions.py @@ -185,11 +185,24 @@ 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): + 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], names=["seeds", "seeds2"]) assert utils.from_currsys(tbl["seeds2"][1]) is None + def test_converts_string_numericals_to_floats(self): + 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__! diff --git a/scopesim/utils.py b/scopesim/utils.py index 78ee3a98..043f0586 100644 --- a/scopesim/utils.py +++ b/scopesim/utils.py @@ -864,11 +864,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 (TypeError, ValueError): + pass return item 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