From d48a3ab99919df8861a57ec3191eb5df5251483b Mon Sep 17 00:00:00 2001 From: Julien R M Lhermitte Date: Mon, 19 Mar 2018 21:13:35 -0400 Subject: [PATCH] Ensure that changes to value, limits and fit update the parent --- hkl/calc.py | 10 +++++--- hkl/engine.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/hkl/calc.py b/hkl/calc.py index 50f761a3..788f9491 100644 --- a/hkl/calc.py +++ b/hkl/calc.py @@ -5,7 +5,7 @@ import numpy as np -from .engine import (Engine, Parameter) +from .engine import (Engine, CalcParameter) from .sample import HklSample from . import util from .util import hkl_module @@ -399,16 +399,20 @@ def _get_axis_by_name(self, name): name = self._axis_name_to_original.get(name, name) return self._geometry.axis_get(name) + def _set_axis_by_name(self, name, axis): + self._geometry.axis_set(name, axis) + @property def units(self): '''The units used for calculations''' return self._unit_name def __getitem__(self, axis): - return Parameter(self._get_axis_by_name(axis), + return CalcParameter(self._get_axis_by_name(axis), units=self._unit_name, name=axis, - inverted=axis in self._inverted_axes) + inverted=axis in self._inverted_axes, + geometry=self._geometry) def __setitem__(self, axis, value): param = self[axis] diff --git a/hkl/engine.py b/hkl/engine.py index 20fa457c..cacaa325 100644 --- a/hkl/engine.py +++ b/hkl/engine.py @@ -40,6 +40,10 @@ def name(self): return '{} (internally: {})'.format(self._name, name) return name + @property + def param_name(self): + return self._param.name_get() + @property def value(self): return self._param.value_get(self._units) @@ -267,3 +271,65 @@ def _repr_info(self): def __repr__(self): return '{}({})'.format(self.__class__.__name__, ', '.join(self._repr_info())) + +# the parameter for the calc object +# this is a fix for backwards compatibility +# when updating parameters we need to update the parent geometry object +class CalcParameter(Parameter): + def __init__(self, *args, geometry=None, **kwargs): + ''' + Like calc parameter but needs reference to a geometry object. + Updates to the parameter should be propagated back to the geometry. + ''' + super().__init__(*args, **kwargs) + self._geometry = geometry + + @property + def limits(self): + if self._inverted: + low, high = self._param.min_max_get(self._units) + return [-high, -low] + else: + return self._param.min_max_get(self._units) + + @limits.setter + def limits(self, lims): + low, high = lims + if self._inverted: + low, high = -high, -low + self._param.min_max_set(low, high, self._units) + if self._geometry is not None: + # param name is the true name of axis + axis = self._geometry.axis_get(self.param_name) + axis.min_max_set(low, high, self._units) + self._geometry.axis_set(self.param_name, axis) + + @property + def value(self): + return self._param.value_get(self._units) + + @value.setter + def value(self, value): + if self._inverted: + value *= -1.0 + + self._param.value_set(value, self._units) + if self._geometry is not None: + # param name is the true name of axis + axis = self._geometry.axis_get(self.param_name) + axis.value_set(value, self._units) + self._geometry.axis_set(self.param_name, axis) + + @property + def fit(self): + '''True if the parameter can be fit or not''' + return bool(self._param.fit_get()) + + @fit.setter + def fit(self, fit): + self._param.fit_set(int(fit)) + if self._geometry is not None: + # param name is the true name of axis + axis = self._geometry.axis_get(self.param_name) + axis.fit_set(fit) + self._geometry.axis_set(self.param_name, axis)