Source code for scopesim.effects.effects_utils

"""TBA."""

import inspect
from copy import deepcopy, copy
from collections.abc import Iterable

from astropy.table import Table

from .. import effects as efs
from ..utils import get_logger


logger = get_logger(__name__)


[docs]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.FilterWheelBase)) and not isinstance(eff, efs.SurfaceList)] if not surflist_list: surflist_list = [empty_surface_list(name="combined_surface_list")] new_surflist = copy(surflist_list[0]) for surflist in surflist_list[1:]: new_surflist.add_surface_list(surflist) # ..todo:: should read position from the list positions in surface_effects for surf in surf_list: position = surf.meta.get("position", -1) new_surflist.add_surface(surf, surf.meta["name"], position=position) return new_surflist
[docs]def get_all_effects(effects, effect_class): if isinstance(effect_class, (list, tuple)): my_effects = [] for eff_cls in effect_class: my_effects += get_all_effects(effects, eff_cls) else: my_effects = [eff for eff in effects if isinstance(eff, effect_class) and eff.include] return my_effects
[docs]def make_effect(effect_dict, cmds=None, **properties): effect_meta_dict = {key: effect_dict[key] for key in effect_dict if key not in ["class", "kwargs"]} effect_class_name = effect_dict["class"] effect_cls = getattr(efs, effect_class_name) # ..todo: add looking for custom effect class names from 3rd party packages effect_kwargs = {} effect_kwargs.update(effect_meta_dict) # effect name and description effect_kwargs.update(properties) # optical_element properties if "kwargs" in effect_dict: effect_kwargs.update(effect_dict["kwargs"]) # individual effect kwargs effect = effect_cls(cmds=cmds, **effect_kwargs) return effect
[docs]def is_spectroscope(effects): spec_classes = (efs.SpectralTraceList, efs.SpectralTraceListWheel) return any(isinstance(eff, spec_classes) for eff in effects)
[docs]def empty_surface_list(**kwargs): tbl = Table(names=["name", "outer", "inner", "angle", "temperature", "action", "filename"], data=[["test"], [0.], [0.], [0.], [0.], ["none"], ["none"]], meta={"outer_unit": "m", "inner_unit": "m", "angle_unit": "deg", "temperature_unit": "deg_C"}) return efs.SurfaceList(table=tbl[:0], **kwargs)
[docs]def scopesim_effect_classes(base_effect=efs.Effect): members = inspect.getmembers(efs) efs_dict = {".".join([cls.__module__, cls.__name__]).replace("scopesim.effects.", ""): cls for name, cls in members if hasattr(cls, "__mro__") and base_effect in cls.__mro__} sorted_effects = {key: efs_dict[key] for key in sorted(efs_dict)} return sorted_effects
[docs]def z_order_in_range(z_eff, z_range: range) -> bool: """ Return True if any of the z_orders in `z_eff` is in the given range. The `z_range` parameter can be constructed as ``range(z_min, z_max)``. Parameters ---------- z_eff : int or list of ints z_order(s) of the effect. z_range : range range object of allowed z_order values. Returns ------- bool True if at least one z_order is in range, False otherwise. """ if not isinstance(z_eff, Iterable): logger.warning("z_order %d should be a single-item iterable", z_eff) z_eff = [z_eff] return any(zi in z_range for zi in z_eff)