Skip to content

Commit b93fb35

Browse files
authored
Refactor and cleanup in OpticalElement (#700)
2 parents a45a9da + 8a487a2 commit b93fb35

1 file changed

Lines changed: 43 additions & 33 deletions

File tree

scopesim/optics/optical_element.py

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1+
# -*- coding: utf-8 -*-
2+
"""Contains ``OpticalElement``, which stores ``Effect``s."""
3+
14
from inspect import isclass
25
from typing import TextIO
36
from io import StringIO
7+
from collections.abc import Mapping
48

59
from astropy.table import Table
610

711
from .. import effects as efs
8-
from ..effects.effects_utils import (make_effect, get_all_effects,
9-
z_order_in_range)
12+
from ..effects.effects_utils import make_effect, z_order_in_range
1013
from ..utils import write_report, get_logger
1114
from ..reports.rst_utils import table_to_rst
12-
from .. import rc
1315

1416

1517
logger = get_logger(__name__)
@@ -64,33 +66,37 @@ def __init__(self, yaml_dict=None, cmds=None, **kwargs):
6466
self.effects = []
6567
self.cmds = cmds
6668

67-
if isinstance(yaml_dict, dict):
68-
self.meta.update({key: yaml_dict[key] for key in yaml_dict
69-
if key not in {"properties", "effects"}})
70-
if "properties" in yaml_dict:
71-
self.properties = yaml_dict["properties"] or {}
72-
if "name" in yaml_dict:
73-
self.properties["element_name"] = yaml_dict["name"]
74-
if "effects" in yaml_dict and len(yaml_dict["effects"]) > 0:
75-
for eff_dic in yaml_dict["effects"]:
76-
if "name" in eff_dic and hasattr(self.cmds,
77-
"ignore_effects"):
78-
if eff_dic["name"] in self.cmds.ignore_effects:
79-
eff_dic["include"] = False
80-
81-
self.effects.append(make_effect(eff_dic,
82-
self.cmds,
83-
**self.properties))
84-
85-
def add_effect(self, effect):
69+
if not isinstance(yaml_dict, Mapping):
70+
return
71+
72+
self.meta.update({key: yaml_dict[key] for key in yaml_dict
73+
if key not in {"properties", "effects"}})
74+
self.properties = yaml_dict.get("properties", {})
75+
# FIXME: Why meta["name"] and also properties["element_name"] ??
76+
self.properties["element_name"] = yaml_dict.get("name")
77+
78+
if "effects" not in yaml_dict or len(yaml_dict["effects"]) == 0:
79+
return
80+
81+
for eff_dic in yaml_dict["effects"]:
82+
if eff_dic.get("name") in getattr(self.cmds, "ignore_effects", []):
83+
eff_dic["include"] = False
84+
85+
self.effects.append(make_effect(eff_dic, self.cmds,
86+
**self.properties))
87+
88+
def add_effect(self, effect: efs.Effect) -> None:
89+
"""Add `effect` to self if it's a valid ``Effect``."""
8690
if isinstance(effect, efs.Effect):
8791
self.effects.append(effect)
8892
else:
8993
logger.warning("%s is not an Effect object and was not added",
9094
effect)
9195

9296
def get_all(self, effect_class):
93-
return get_all_effects(self.effects, effect_class)
97+
"""Return a list of all effects in self that match `effect_class`."""
98+
return list(self._get_matching_effects(effect_class,
99+
only_included=True))
94100

95101
def get_z_order_effects(self, z_level: int, z_max: int = None):
96102
"""
@@ -144,20 +150,21 @@ def get_z_order_effects(self, z_level: int, z_max: int = None):
144150
if z_order_in_range(eff.z_order, z_range):
145151
yield eff
146152

147-
def _get_matching_effects(self, effect_classes):
148-
return (eff for eff in self.effects if isinstance(eff, effect_classes))
153+
def _get_matching_effects(self, effect_classes, only_included=False):
154+
return (eff for eff in self.effects if isinstance(eff, effect_classes)
155+
and eff.include or not only_included)
149156

150157
@property
151-
def surfaces_list(self):
158+
def surfaces_list(self) -> list[efs.Effect]:
152159
effect_classes = (efs.SurfaceList, efs.FilterWheel, efs.TERCurve)
153160
return list(self._get_matching_effects(effect_classes))
154161

155162
@property
156-
def masks_list(self):
163+
def masks_list(self) -> list[efs.Effect]:
157164
effect_classes = (efs.ApertureList, efs.ApertureMask)
158165
return list(self._get_matching_effects(effect_classes))
159166

160-
def list_effects(self):
167+
def list_effects(self) -> Table:
161168
elements = [self.meta["name"]] * len(self.effects)
162169
names = [eff.display_name for eff in self.effects]
163170
classes = [eff.__class__.__name__ for eff in self.effects]
@@ -170,7 +177,7 @@ def list_effects(self):
170177

171178
return tbl
172179

173-
def __add__(self, other):
180+
def __add__(self, other) -> None:
174181
self.add_effect(other)
175182

176183
def __getitem__(self, item):
@@ -239,13 +246,16 @@ def pretty_str(self) -> str:
239246
return output
240247

241248
@property
242-
def display_name(self):
249+
def display_name(self) -> str:
250+
"""Return name or filename or placeholder."""
243251
return self.meta.get("name", self.meta.get("filename", "<empty>"))
244252

245-
def __repr__(self):
253+
def __repr__(self) -> str:
254+
"""Return repr(self)."""
246255
return f"<{self.__class__.__name__}>"
247256

248-
def __str__(self):
257+
def __str__(self) -> str:
258+
"""Return str(self)."""
249259
return f"{self.__class__.__name__}: \"{self.display_name}\""
250260

251261
def _repr_pretty_(self, p, cycle):
@@ -256,7 +266,7 @@ def _repr_pretty_(self, p, cycle):
256266
p.text(str(self))
257267

258268
@property
259-
def properties_str(self):
269+
def properties_str(self) -> str:
260270
# TODO: This seems to be used only in the report below.
261271
# Once the report uses stream writing, change this to a function
262272
# that simply write to that same stream...

0 commit comments

Comments
 (0)