;iE>ddlZddlmZddlmZddlZddlmZ Gdde Z e dkrnGd d e Z e Zd e_de_de_d e_de_eeedSdS) N) OrderedDict)log2) functionsc|eZdZdZeZdZdZdZdZ dZ dZ dd Z d Z d Zd ZdZdZdZdZdS) SystemSolvera This abstract class is used to formalize and manage user interaction with a complex system of equations (related to "constraint satisfaction problems"). It is often the case that devices must be controlled through a large number of free variables, and interactions between these variables make the system difficult to manage and conceptualize as a user interface. This class does _not_ attempt to numerically solve the system of equations. Rather, it provides a framework for subdividing the system into manageable pieces and specifying closed-form solutions to these small pieces. For an example, see the simple Camera class below. Theory of operation: Conceptualize the system as 1) a set of variables whose values may be either user-specified or automatically generated, and 2) a set of functions that define *how* each variable should be generated. When a variable is accessed (as an instance attribute), the solver first checks to see if it already has a value (either user-supplied, or cached from a previous calculation). If it does not, then the solver calls a method on itself (the method must be named `_variableName`) that will either return the calculated value (which usually involves acccessing other variables in the system), or raise RuntimeError if it is unable to calculate the value (usually because the user has not provided sufficient input to fully constrain the system). Each method that calculates a variable value may include multiple try/except blocks, so that if one method generates a RuntimeError, it may fall back on others. In this way, the system may be solved by recursively searching the tree of possible relationships between variables. This allows the user flexibility in deciding which variables are the most important to specify, while avoiding the apparent combinatorial explosion of calculation pathways that must be considered by the developer. Solved values are cached for efficiency, and automatically cleared when a state change invalidates the cache. The rules for this are simple: any time a value is set, it invalidates the cache *unless* the previous value was None (which indicates that no other variable has yet requested that value). More complex cache management may be defined in subclasses. Subclasses must define: 1) The *defaultState* class attribute: This is a dict containing a description of the variables in the system--their default values, data types, and the ways they can be constrained. The format is:: { name: [value, type, constraint, allowed_constraints], ...} Where: * *value* is the default value. May be None if it has not been specified yet. * *type* may be float, int, bool, np.ndarray, ... * *constraint* may be None, single value, or (min, max) * None indicates that the value is not constrained--it may be automatically generated if the value is requested. * *allowed_constraints* is a string composed of (n)one, (f)ixed, and (r)ange. Note: do not put mutable objects inside defaultState! 2) For each variable that may be automatically determined, a method must be defined with the name `_variableName`. This method may either return the ct|jd<t|jd<|dSN_vars _currentGets)r__dict__setreset)selfs XC:\PYTHON\MyICR_Workspace\venv\Lib\site-packages\pyqtgraph/parametertree/SystemSolver.py__init__zSystemSolver.__init__Ns3!, g(+ n% ct|}tj|jd|jd<tj|jd|jd<|Sr )typecopydeepcopyr )rsyss rrzSystemSolver.copySsRd4jjll $ dmG.D E E W'+}T]>5R'S'S ^$ rc|j|jD]}|j|dd|j|< dS)zK Reset all variables in the solver to their default state. N)r clear defaultStater rks rrzSystemSolver.resetYsS !!!" 4 4A -a03DJqMM 4 4rc\||jvr||St|N)r getAttributeError)rnames r __getattr__zSystemSolver.__getattr__as- 4:  88D>> !T"""rc||jvr||||ddSt|tr8|j|dtjur||d|dS|||ddSt ||rt|||dSt|)a= Set the value of a state variable. If None is given for the value, then the constraint will also be set to None. If a tuple is given for a scalar variable, then the tuple is used as a range constraint instead of a value. Otherwise, the constraint is set to 'fixed'. Nfixed) r r isinstancetuplenpndarrayhasattrobject __setattr__r!)rr"values rr-zSystemSolver.__setattr__fs 4:  }ud+++++E5)) /dj.>q.A.S.StU+++++ug.....tT"" +""4u55555$T***rc||jvrtd|z|j| |j|d}|Mt |d|zd}|d}n |}|td|z|||}|j|n#|j|wxYw|S)z Return the value for parameter *name*. If the value has not been specified, then attempt to compute it from other interacting parameters. If no value can be determined, then raise RuntimeError. z)Cyclic dependency while calculating '%s'.rN_z Parameter '%s' is not specified.)r RuntimeErroraddr getattrrremove)rr"vcfuncs rr zSystemSolver.get}s 4$ $ $"#NQU#UVVV d### + 4 #AycDj$77=AAA9&'ID'PQQQHHT1%%   $ $T * * * *D  $ $T * * * *s A"B44CNTc |j|}|"d|dvrtd|z||d<n|dkr"d|dvrtd|z||d<nbt|tr7d |dvrtd |zt |dksJ||d<n|d urtd |z|d t jur|t j|t}n/|d tttfvr||d |}|d ur4| ||std|d|d|d|d|| ||d<|S)a Set a variable *name* to *value*. The actual set value is returned (in some cases, the value may be cast into another type). If *value* is None, then the value is left to be determined in the future. At any time, the value may be re-assigned arbitrarily unless a constraint is given. If *constraint* is True (the default), then supplying a value that violates a previously specified constraint will raise an exception. If *constraint* is 'fixed', then the value is set (if provided) and the variable will not be updated automatically in the future. If *constraint* is a tuple, then the value is constrained to be within the given (min, max). Either constraint may be None to disable it. In some cases, a constraint cannot be satisfied automatically, and the user will be forced to resolve the constraint manually. If *constraint* is None, then any constraints are removed for the variable. Nnz&Empty constraints not allowed for '%s'rr&fz&Fixed constraints not allowed for '%s'rz&Range constraints not allowed for '%s'Tz:constraint must be None, True, 'fixed', or tuple. (got %s)r%)dtypezSetting z = z violates constraint r) r TypeErrorr'r(lenr)r*arrayfloatintcheck_constraint ValueError resetUnfixed)rr"r. constraintvars rrzSystemSolver.sets,j  #a&   H4 OPPPCFF 7 " "#a&   H4 OPPP CFF  E * * g#a&   H4 OPPPz??a''''CFF t # #X[eeff f q6RZ  E$5HU%000EE VUE* * *u/@CF5MME   d&;&;D%&H&H *uuuVYZ[V\V\]^^ ^ q6       A rc|j|d}||dSt|tr,|ddus |d|ko|ddup |d|kS||kS)NrTrr%)r r'r()rr"r.cs rrBzSystemSolver.check_constraintsy Jt Q  9 4 a   qTT\2QqTU]4qTT\2QqTU] 5A: rct}|jD]\}}|d|df||<|S)zR Return a serializable description of the solver's current state. rr)rr itemsrstater"rFs r saveStatezSystemSolver.saveStatesK ))++ + +ID#q63q6*E$KK rc||D](\}}|||d|d)dS)zP Restore the state of all values and constraints in the solver. rr%N)rrJrrKs r restoreStatezSystemSolver.restoreStatesW  + +ID# HHT3q63q6 * * * * + +rc`|jD]}|ddkrd|d<dS)ze For any variable that does not have a fixed value, reset its value to None. rr&Nr)r values)rrFs rrDzSystemSolver.resetUnfixedsD :$$&&  C1v  A  rc:|jD]}t||dSr)r r3rs rsolvezSystemSolver.solves0  A D!      rcP|jD]\}}|ddkrzd|dvrp|dd}||dd |||||j|<cS#t$rYnwxYw ||j|<|#||j|<wxYwdS)aUCheck whether the system is overconstrained. If so, return the name of the first overconstrained parameter. Overconstraints occur when any fixed parameter can be successfully computed by the system. (Ideally, all parameters are either fixed by the user or constrained by the system, but never both). rr&r8r9NF)r rJrr r1)rrr5oldvals rcheckOverconstraintz SystemSolver.checkOverconstraints:##%% + +CAatw3!A$;;111D$'''+HHQKKK%+DJqMMMM$D$*DJqMMFDJqM****us$A:: BBBB B"ct}|jD]\}}|ddkr |d||<dd|D}d|jjd|dS) Nrr&rz, c"g|] \}}|d| S)=).0r8r5s r z)SystemSolver.__repr__..%s'EEE!aaa+EEEr< >)rr rJjoin __class____name__rKs r__repr__zSystemSolver.__repr__ s ))++ % %ID#1v  !!fd  EEu{{}}EEEFF N333UUU;;r)NT)rb __module__ __qualname____doc__rrrrrr#r-r rrBrMrOrDrSrVrcrZrrrr s??B;==L  444### +++.8DDDDL+++2<<<<rs, ######\<\<\<\<\<6\<\<\