Skip to content

Commit ec33de6

Browse files
committed
support writing compute_checks in feature classes
1 parent 50680f6 commit ec33de6

File tree

4 files changed

+51
-18
lines changed

4 files changed

+51
-18
lines changed

phoebe/backend/universe.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,16 +1246,12 @@ def from_bundle(cls, b, component, compute=None,
12461246

12471247
features = []
12481248
for feature in b.filter(qualifier='enabled', compute=compute, value=True, **_skip_filter_checks).features:
1249-
feature_ps = b.get_feature(feature=feature, **_skip_filter_checks)
12501249
if feature_ps.component != component:
12511250
continue
12521251
if feature_ps.get_value(qualifier='feature_type', **_skip_filter_checks) != 'component':
12531252
continue
1254-
if 'custom_code' in feature_ps.qualifiers:
1255-
feature_cls = feature_ps.get_value(qualifier='custom_code', **_skip_filter_checks)
1256-
else:
1257-
feature_cls = getattr(component_features, feature_ps.kind.title())
1258-
features.append(feature_cls.from_bundle(b, feature_ps))
1253+
feature_obj = b.get_feature_code(feature=feature)
1254+
features.append(feature_obj)
12591255

12601256
if conf.devel:
12611257
mesh_offset_override = kwargs.pop('mesh_offset', None)

phoebe/features/common.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def __init__(self, **kwargs):
66
self.kwargs = kwargs
77

88
@classmethod
9-
def create_feature_parameters(self, feature, **kwargs):
9+
def create_feature_parameters(self, feature_ps, **kwargs):
1010
raise NotImplementedError("create_feature_parameters must be implemented in the feature subclass")
1111

1212
@classmethod
@@ -30,5 +30,9 @@ def parse_bundle(cls, b, feature_ps):
3030
return {}
3131

3232
@classmethod
33-
def from_bundle(cls, b, feature_ps):
33+
def _from_bundle(cls, b, feature_ps):
3434
return cls(**cls.parse_bundle(b, feature_ps))
35+
36+
@classmethod
37+
def run_checks_compute(cls, b, feature_ps, compute_ps):
38+
return [{}]

phoebe/features/component_features.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,8 @@ def create_feature_parameters(cls, feature, **kwargs):
151151
params = []
152152
params += [FloatParameter(qualifier="colat", value=kwargs.get('colat', 0.0), default_unit=u.deg, description='Colatitude of the center of the spot wrt spin axis')]
153153
params += [FloatParameter(qualifier="long", value=kwargs.get('long', 0.0), default_unit=u.deg, description='Longitude of the center of the spot wrt spin axis')]
154-
params += [FloatParameter(qualifier='radius', value=kwargs.get('radius', 1.0), default_unit=u.deg, description='Angular radius of the spot')]
155-
params += [FloatParameter(qualifier='relteff', value=kwargs.get('relteff', 1.0), limits=(0.,None), default_unit=u.dimensionless_unscaled, description='Temperature of the spot relative to the intrinsic temperature')]
154+
params += [FloatParameter(qualifier='radius', value=kwargs.get('radius', 1.0), limits=(0, 180), default_unit=u.deg, description='Angular radius of the spot')]
155+
params += [FloatParameter(qualifier='relteff', value=kwargs.get('relteff', 1.0), limits=(0, None), default_unit=u.dimensionless_unscaled, description='Temperature of the spot relative to the intrinsic temperature')]
156156

157157
return ParameterSet(params), []
158158

@@ -188,6 +188,21 @@ def parse_bundle(cls, b, feature_ps):
188188

189189
return dict(colat=colat, longitude=longitude, rot_dlongdt=rot_dlongdt, radius=radius, relteff=relteff, t0=t0)
190190

191+
@classmethod
192+
def run_checks_compute(cls, b, feature_ps, compute_ps):
193+
items = []
194+
relteff_param = feature_ps.get_parameter(qualifier='relteff', **_skip_filter_checks)
195+
radius_param = feature_ps.get_parameter(qualifier='radius', **_skip_filter_checks)
196+
if relteff_param.get_value(**_skip_filter_checks) == 1:
197+
items += [{'msg': 'relteff of spot is 1.0 which will have no affect',
198+
'params': [relteff_param],
199+
'is_error': False}]
200+
if radius_param.get_value(**_skip_filter_checks) == 0:
201+
items += [{'msg': 'radius of spot is 0.0 which will have no affect',
202+
'params': [radius_param],
203+
'is_error': False}]
204+
return items
205+
191206
def instantaneous_position(self, s, time):
192207
"""
193208
s is the spin vector in roche coordinates

phoebe/frontend/bundle.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3175,19 +3175,20 @@ def run_checks(self, raise_logger_warning=False, raise_error=False, **kwargs):
31753175
Arguments
31763176
-----------
31773177
* `compute` (string or list of strings, optional, default=None): the
3178-
compute options to use when running checks. If None (or not provided),
3178+
compute options to use when running checks. If None (or not provided),
31793179
the compute options in the 'run_checks_compute@setting' parameter
31803180
will be used (which defaults to all available compute options).
3181+
All enabled features in `compute` will also be checked.
31813182
* `solver` (string or list of strings, optional, default=None): the
3182-
solver options to use when running checks. If None (or not provided),
3183+
solver options to use when running checks. If None (or not provided),
31833184
the compute options in the 'run_checks_solver@setting' parameter
31843185
will be used (which defaults to all available solver options).
31853186
* `solution` (string or list of strings, optional, default=None): the
3186-
solutions to use when running checks. If None (or not provided),
3187+
solutions to use when running checks. If None (or not provided),
31873188
the compute options in the 'run_checks_solution@setting' parameter
31883189
will be used (which defaults to no solutions, if not set).
31893190
* `figure` (string or list of strings, optional, default=None): the
3190-
figures to use when running checks. If None (or not provided),
3191+
figures to use when running checks. If None (or not provided),
31913192
the compute options in the 'run_checks_figure@setting' parameter
31923193
will be used (which defaults to no figures, if not set).
31933194
* `allow_skip_constraints` (bool, optional, default=False): whether
@@ -4034,10 +4035,12 @@ def _get_surf_area(comp):
40344035

40354036

40364037
for compute in computes:
4037-
compute_kind = self.get_compute(compute=compute, **_skip_filter_checks).kind
4038+
compute_ps = self.get_compute(compute=compute, **_skip_filter_checks)
4039+
compute_kind = compute_ps.kind
40384040

40394041
gps = self.filter(kind=['gp_celerite2','gp_sklearn'], context='feature', **_skip_filter_checks).features
40404042
compute_enabled_gps = self.filter(qualifier='enabled', compute=compute, feature=gps, value=True, **_skip_filter_checks).features
4043+
compute_enabled_features = self.filter(qualifier='enabled', compute=compute, value=True, **_skip_filter_checks).features
40414044
compute_enabled_datasets = self.filter(qualifier='enabled', dataset=self.datasets, value=True, **_skip_filter_checks).datasets
40424045
compute_enabled_datasets_with_gps = [ds for ds in self.filter(feature=compute_enabled_gps, **_skip_filter_checks).datasets if ds in compute_enabled_datasets]
40434046

@@ -4118,6 +4121,16 @@ def _get_surf_area(comp):
41184121
else:
41194122
raise ValueError("{} could not be found in distributions or solutions".format(dist_or_solution))
41204123

4124+
for feature in compute_enabled_features:
4125+
feature_ps = self.get_feature(feature=feature, **_skip_filter_checks)
4126+
feature_cls = self.get_feature_code(feature=feature, instantiate=False)
4127+
for item in feature_cls.run_checks_compute(b=self, feature_ps=feature_ps, compute_ps=compute_ps):
4128+
report.add_item(self,
4129+
item.get('msg'),
4130+
item.get('params', []),
4131+
item.get('is_error', False),
4132+
'run_compute')
4133+
41214134
if len(compute_enabled_gps):
41224135
# check for time-dependency issues with GPs
41234136
# then if we're using compute_times/phases, compute_times must cover the range of the dataset times
@@ -5711,16 +5724,18 @@ def get_feature(self, feature=None, **kwargs):
57115724
kwargs['context'] = 'feature'
57125725
return self.filter(**kwargs)
57135726

5714-
def get_feature_code(self, feature=None, **kwargs):
5727+
def get_feature_code(self, feature=None, instantiate=True, **kwargs):
57155728
"""
5716-
Get the instantiated object containing the logic to run a feature.
5729+
Get the instantiated object (or non-instantiated class) containing the logic to run a feature.
57175730

57185731
See also:
57195732
* <phoebe.frontend.bundle.Bundle.get_feature>
57205733

57215734
Arguments
57225735
---------
57235736
* `feature`: (string, optional, default=None): the name of the feature
5737+
* `instantiate`: (bool, optional, default=True): whether to intstantiate the object
5738+
or return the class
57245739
* `**kwargs`: any other tags to do the filtering (excluding feature and context)
57255740

57265741
Returns:
@@ -5731,7 +5746,10 @@ def get_feature_code(self, feature=None, **kwargs):
57315746
cls = feature_ps.get_value(qualifier='custom_code', check_visible=False, check_default=False)
57325747
else:
57335748
cls = _feature._feature_classes.get(feature_ps.kind)
5734-
return cls.from_bundle(self, feature_ps)
5749+
if instantiate:
5750+
return cls._from_bundle(self, feature_ps)
5751+
else:
5752+
return cls
57355753

57365754
@send_if_client
57375755
def remove_feature(self, feature=None, return_changes=False, **kwargs):

0 commit comments

Comments
 (0)