ADR Suggestion
Dependent Parameters
#10
Replies: 2 comments 1 reply
-
Note that in order to update the part of the GUI that displays the changed parameter, you must decorate the setter and getter of the parameter and emit the parameter changed signal, as shown in the example below: from PySide6.QtCore import QObject, Signal, Slot, Property
class Model(QObject):
definedChanged = Signal()
def __init__(self):
self._defined = False
@Property(bool, notify=definedChanged)
def defined(self):
return self._defined
@defined.setter
def defined(self, newValue):
if self._defined == newValue:
return
self._defined = newValue
self.definedChanged.emit() Now every time you assign a new value to the property |
Beta Was this translation helpful? Give feedback.
-
To my understanding we would also need functionality to inform the independent parameter when a new dependent parameter is made dependent. |
Beta Was this translation helpful? Give feedback.
-
General
It can be beneficial in a model to have Parameters which are defined through a relation to other parameters/descriptors. These dependent parameters are defined by their relation and thus should not be fitted during minimization. Their value should be updated when the values of the independent parameters which they depend on are changed. It should be possible to easily convert a dependent parameter to a dependent parameter and vice versa.
Current Implementation
Currently, this is handled by the "constraints" objects which are created separately and then assigned to the parameter, such as:
Proposed Implementation
The concept of a dependent
Parameter
can be implemented using the generic "Observer" coding pattern, with all the dependent parameters being observers subscribing to the independent parameters. The update of a dependent parameter can be done using theasteval
python interpreter with its functionality limited to only arithmetic and logical operation, and its symtable including only the independent parameters.The observer pattern
The observer pattern is a fairly simple pattern including only 4 basic methods and 1 attribute:
This is the basic construct of the observed object, here namely the independent parameters. Since a dependent
Parameter
can use aDescriptorNumber
for its relation, this part of the observer pattern should be implemented on theDescriptorNumber
Since only
Parameters
can be a dependent parameter, the_update
method is defined in theParameter
class.The string value evaluation with
asteval
At startup, a python interpreter is created in the
global_object
, usingasteval
to limit its functionality to only arithmetic and logical expressions, to avoid many of the potential safety issues with embedded interpreters: https://lmfit.github.io/asteval/motivation.html.The user makes a value dependent by setting its value to a string:
When a value is set by a string, the internal attribute
_independent
is set toFalse
, thefixed
attribute is set toTrue
, the string is scanned forParameters
andDescriptorNumbers
which are added to theasteval
s interpreterssymtable
, the_update
method is called and the setters on theParameter
can no longer be used.The
_update
method runs the value string expression through theasteval
interpreter and sets theParameters
attributes to the output of the expression:Requirements
Beta Was this translation helpful? Give feedback.
All reactions