+ if self.__Xb is None: __Xb_shape = (0,)
+ elif hasattr(self.__Xb,"size"): __Xb_shape = (self.__Xb.size,)
+ elif hasattr(self.__Xb,"shape"):
+ if isinstance(self.__Xb.shape, tuple): __Xb_shape = self.__Xb.shape
+ else: __Xb_shape = self.__Xb.shape()
+ else: raise TypeError("The background (Xb) has no attribute of shape: problem !")
+ #
+ if self.__Y is None: __Y_shape = (0,)
+ elif hasattr(self.__Y,"size"): __Y_shape = (self.__Y.size,)
+ elif hasattr(self.__Y,"shape"):
+ if isinstance(self.__Y.shape, tuple): __Y_shape = self.__Y.shape
+ else: __Y_shape = self.__Y.shape()
+ else: raise TypeError("The observation (Y) has no attribute of shape: problem !")
+ #
+ if self.__U is None: __U_shape = (0,)
+ elif hasattr(self.__U,"size"): __U_shape = (self.__U.size,)
+ elif hasattr(self.__U,"shape"):
+ if isinstance(self.__U.shape, tuple): __U_shape = self.__U.shape
+ else: __U_shape = self.__U.shape()
+ else: raise TypeError("The control (U) has no attribute of shape: problem !")
+ #
+ if self.__B is None: __B_shape = (0,0)
+ elif hasattr(self.__B,"shape"):
+ if isinstance(self.__B.shape, tuple): __B_shape = self.__B.shape
+ else: __B_shape = self.__B.shape()
+ else: raise TypeError("The a priori errors covariance matrix (B) has no attribute of shape: problem !")
+ #
+ if self.__R is None: __R_shape = (0,0)
+ elif hasattr(self.__R,"shape"):
+ if isinstance(self.__R.shape, tuple): __R_shape = self.__R.shape
+ else: __R_shape = self.__R.shape()
+ else: raise TypeError("The observation errors covariance matrix (R) has no attribute of shape: problem !")
+ #
+ if self.__Q is None: __Q_shape = (0,0)
+ elif hasattr(self.__Q,"shape"):
+ if isinstance(self.__Q.shape, tuple): __Q_shape = self.__Q.shape
+ else: __Q_shape = self.__Q.shape()
+ else: raise TypeError("The evolution errors covariance matrix (Q) has no attribute of shape: problem !")
+ #
+ if len(self.__HO) == 0: __HO_shape = (0,0)
+ elif isinstance(self.__HO, dict): __HO_shape = (0,0)
+ elif hasattr(self.__HO["Direct"],"shape"):
+ if isinstance(self.__HO["Direct"].shape, tuple): __HO_shape = self.__HO["Direct"].shape
+ else: __HO_shape = self.__HO["Direct"].shape()
+ else: raise TypeError("The observation operator (H) has no attribute of shape: problem !")
+ #
+ if len(self.__EM) == 0: __EM_shape = (0,0)
+ elif isinstance(self.__EM, dict): __EM_shape = (0,0)
+ elif hasattr(self.__EM["Direct"],"shape"):
+ if isinstance(self.__EM["Direct"].shape, tuple): __EM_shape = self.__EM["Direct"].shape
+ else: __EM_shape = self.__EM["Direct"].shape()
+ else: raise TypeError("The evolution model (EM) has no attribute of shape: problem !")
+ #
+ if len(self.__CM) == 0: __CM_shape = (0,0)
+ elif isinstance(self.__CM, dict): __CM_shape = (0,0)
+ elif hasattr(self.__CM["Direct"],"shape"):
+ if isinstance(self.__CM["Direct"].shape, tuple): __CM_shape = self.__CM["Direct"].shape
+ else: __CM_shape = self.__CM["Direct"].shape()
+ else: raise TypeError("The control model (CM) has no attribute of shape: problem !")
+ #
+ # Vérification des conditions
+ # ---------------------------
+ if not( len(__Xb_shape) == 1 or min(__Xb_shape) == 1 ):
+ raise ValueError("Shape characteristic of background (Xb) is incorrect: \"%s\"."%(__Xb_shape,))
+ if not( len(__Y_shape) == 1 or min(__Y_shape) == 1 ):
+ raise ValueError("Shape characteristic of observation (Y) is incorrect: \"%s\"."%(__Y_shape,))
+ #
+ if not( min(__B_shape) == max(__B_shape) ):
+ raise ValueError("Shape characteristic of a priori errors covariance matrix (B) is incorrect: \"%s\"."%(__B_shape,))
+ if not( min(__R_shape) == max(__R_shape) ):
+ raise ValueError("Shape characteristic of observation errors covariance matrix (R) is incorrect: \"%s\"."%(__R_shape,))
+ if not( min(__Q_shape) == max(__Q_shape) ):
+ raise ValueError("Shape characteristic of evolution errors covariance matrix (Q) is incorrect: \"%s\"."%(__Q_shape,))
+ if not( min(__EM_shape) == max(__EM_shape) ):
+ raise ValueError("Shape characteristic of evolution operator (EM) is incorrect: \"%s\"."%(__EM_shape,))
+ #
+ if len(self.__HO) > 0 and not isinstance(self.__HO, dict) and not( __HO_shape[1] == max(__Xb_shape) ):
+ raise ValueError("Shape characteristic of observation operator (H) \"%s\" and state (X) \"%s\" are incompatible."%(__HO_shape,__Xb_shape))
+ if len(self.__HO) > 0 and not isinstance(self.__HO, dict) and not( __HO_shape[0] == max(__Y_shape) ):
+ raise ValueError("Shape characteristic of observation operator (H) \"%s\" and observation (Y) \"%s\" are incompatible."%(__HO_shape,__Y_shape))
+ if len(self.__HO) > 0 and not isinstance(self.__HO, dict) and len(self.__B) > 0 and not( __HO_shape[1] == __B_shape[0] ):
+ raise ValueError("Shape characteristic of observation operator (H) \"%s\" and a priori errors covariance matrix (B) \"%s\" are incompatible."%(__HO_shape,__B_shape))
+ if len(self.__HO) > 0 and not isinstance(self.__HO, dict) and len(self.__R) > 0 and not( __HO_shape[0] == __R_shape[1] ):
+ raise ValueError("Shape characteristic of observation operator (H) \"%s\" and observation errors covariance matrix (R) \"%s\" are incompatible."%(__HO_shape,__R_shape))
+ #
+ if self.__B is not None and len(self.__B) > 0 and not( __B_shape[1] == max(__Xb_shape) ):
+ if self.__algorithmName in ["EnsembleBlue",]:
+ asPersistentVector = self.__Xb.reshape((-1,min(__B_shape)))
+ self.__Xb = Persistence.OneVector("Background")
+ for member in asPersistentVector:
+ self.__Xb.store( numpy.asarray(member, dtype=float) )
+ __Xb_shape = min(__B_shape)
+ else:
+ raise ValueError("Shape characteristic of a priori errors covariance matrix (B) \"%s\" and background (Xb) \"%s\" are incompatible."%(__B_shape,__Xb_shape))
+ #
+ if self.__R is not None and len(self.__R) > 0 and not( __R_shape[1] == max(__Y_shape) ):
+ raise ValueError("Shape characteristic of observation errors covariance matrix (R) \"%s\" and observation (Y) \"%s\" are incompatible."%(__R_shape,__Y_shape))
+ #
+ if self.__EM is not None and len(self.__EM) > 0 and not isinstance(self.__EM, dict) and not( __EM_shape[1] == max(__Xb_shape) ):
+ raise ValueError("Shape characteristic of evolution model (EM) \"%s\" and state (X) \"%s\" are incompatible."%(__EM_shape,__Xb_shape))
+ #
+ if self.__CM is not None and len(self.__CM) > 0 and not isinstance(self.__CM, dict) and not( __CM_shape[1] == max(__U_shape) ):
+ raise ValueError("Shape characteristic of control model (CM) \"%s\" and control (U) \"%s\" are incompatible."%(__CM_shape,__U_shape))
+ #
+ if ("Bounds" in self.__P) \
+ and (isinstance(self.__P["Bounds"], list) or isinstance(self.__P["Bounds"], tuple)) \
+ and (len(self.__P["Bounds"]) != max(__Xb_shape)):
+ raise ValueError("The number \"%s\" of bound pairs for the state (X) components is different of the size \"%s\" of the state itself." \
+ %(len(self.__P["Bounds"]),max(__Xb_shape)))
+ #
+ if ("StateBoundsForQuantiles" in self.__P) \
+ and (isinstance(self.__P["StateBoundsForQuantiles"], list) or isinstance(self.__P["StateBoundsForQuantiles"], tuple)) \
+ and (len(self.__P["StateBoundsForQuantiles"]) != max(__Xb_shape)):
+ raise ValueError("The number \"%s\" of bound pairs for the quantile state (X) components is different of the size \"%s\" of the state itself." \
+ %(len(self.__P["StateBoundsForQuantiles"]),max(__Xb_shape)))
+ #
+ return 1
+
+# ==============================================================================
+class RegulationAndParameters(object):
+ """
+ Classe générale d'interface d'action pour la régulation et ses paramètres
+ """
+ def __init__(self,
+ name = "GenericRegulation",
+ asAlgorithm = None,
+ asDict = None,
+ asScript = None,
+ ):
+ """
+ """
+ self.__name = str(name)
+ self.__P = {}
+ #
+ if asAlgorithm is None and asScript is not None:
+ __Algo = Interfaces.ImportFromScript(asScript).getvalue( "Algorithm" )
+ else:
+ __Algo = asAlgorithm
+ #
+ if asDict is None and asScript is not None:
+ __Dict = Interfaces.ImportFromScript(asScript).getvalue( self.__name, "Parameters" )
+ else:
+ __Dict = asDict
+ #
+ if __Dict is not None:
+ self.__P.update( dict(__Dict) )
+ #
+ if __Algo is not None:
+ self.__P.update( {"Algorithm":str(__Algo)} )
+
+ def get(self, key = None):
+ "Vérifie l'existence d'une clé de variable ou de paramètres"
+ if key in self.__P:
+ return self.__P[key]
+ else:
+ return self.__P
+
+# ==============================================================================
+class DataObserver(object):
+ """
+ Classe générale d'interface de type observer
+ """
+ def __init__(self,
+ name = "GenericObserver",
+ onVariable = None,
+ asTemplate = None,
+ asString = None,
+ asScript = None,
+ asObsObject = None,
+ withInfo = None,
+ scheduledBy = None,
+ withAlgo = None,
+ ):
+ """
+ """
+ self.__name = str(name)
+ self.__V = None
+ self.__O = None
+ self.__I = None
+ #
+ if onVariable is None:
+ raise ValueError("setting an observer has to be done over a variable name or a list of variable names, not over None.")
+ elif type(onVariable) in (tuple, list):
+ self.__V = tuple(map( str, onVariable ))
+ if withInfo is None:
+ self.__I = self.__V
+ else:
+ self.__I = (str(withInfo),)*len(self.__V)
+ elif isinstance(onVariable, str):
+ self.__V = (onVariable,)
+ if withInfo is None:
+ self.__I = (onVariable,)
+ else:
+ self.__I = (str(withInfo),)
+ else:
+ raise ValueError("setting an observer has to be done over a variable name or a list of variable names.")
+ #
+ if asObsObject is not None:
+ self.__O = asObsObject
+ else:
+ __FunctionText = str(UserScript('Observer', asTemplate, asString, asScript))
+ __Function = Observer2Func(__FunctionText)
+ self.__O = __Function.getfunc()
+ #
+ for k in range(len(self.__V)):
+ ename = self.__V[k]
+ einfo = self.__I[k]
+ if ename not in withAlgo:
+ raise ValueError("An observer is asked to be set on a variable named %s which does not exist."%ename)
+ else:
+ withAlgo.setObserver(ename, self.__O, einfo, scheduledBy)
+
+ def __repr__(self):
+ "x.__repr__() <==> repr(x)"
+ return repr(self.__V)+"\n"+repr(self.__O)
+
+ def __str__(self):
+ "x.__str__() <==> str(x)"
+ return str(self.__V)+"\n"+str(self.__O)
+
+# ==============================================================================
+class UserScript(object):
+ """
+ Classe générale d'interface de type texte de script utilisateur
+ """
+ def __init__(self,
+ name = "GenericUserScript",
+ asTemplate = None,
+ asString = None,
+ asScript = None,
+ ):
+ """
+ """
+ self.__name = str(name)
+ #
+ if asString is not None:
+ self.__F = asString
+ elif self.__name == "UserPostAnalysis" and (asTemplate is not None) and (asTemplate in Templates.UserPostAnalysisTemplates):
+ self.__F = Templates.UserPostAnalysisTemplates[asTemplate]
+ elif self.__name == "Observer" and (asTemplate is not None) and (asTemplate in Templates.ObserverTemplates):
+ self.__F = Templates.ObserverTemplates[asTemplate]
+ elif asScript is not None:
+ self.__F = Interfaces.ImportFromScript(asScript).getstring()
+ else:
+ self.__F = ""
+
+ def __repr__(self):
+ "x.__repr__() <==> repr(x)"
+ return repr(self.__F)
+
+ def __str__(self):
+ "x.__str__() <==> str(x)"
+ return str(self.__F)
+
+# ==============================================================================
+class ExternalParameters(object):
+ """
+ Classe générale d'interface de type texte de script utilisateur
+ """
+ def __init__(self,
+ name = "GenericExternalParameters",
+ asDict = None,
+ asScript = None,
+ ):
+ """
+ """
+ self.__name = str(name)
+ self.__P = {}
+ #
+ self.updateParameters( asDict, asScript )
+
+ def updateParameters(self,
+ asDict = None,
+ asScript = None,
+ ):
+ "Mise a jour des parametres"
+ if asDict is None and asScript is not None:
+ __Dict = Interfaces.ImportFromScript(asScript).getvalue( self.__name, "ExternalParameters" )
+ else:
+ __Dict = asDict
+ #
+ if __Dict is not None:
+ self.__P.update( dict(__Dict) )
+
+ def get(self, key = None):
+ if key in self.__P:
+ return self.__P[key]
+ else:
+ return list(self.__P.keys())
+
+ def keys(self):
+ return list(self.__P.keys())
+
+ def pop(self, k, d):
+ return self.__P.pop(k, d)
+
+ def items(self):
+ return self.__P.items()
+
+ def __contains__(self, key=None):
+ "D.__contains__(k) -> True if D has a key k, else False"
+ return key in self.__P
+
+# ==============================================================================
+class State(object):
+ """
+ Classe générale d'interface de type état
+ """
+ def __init__(self,
+ name = "GenericVector",
+ asVector = None,
+ asPersistentVector = None,
+ asScript = None,
+ asDataFile = None,
+ colNames = None,
+ colMajor = False,
+ scheduledBy = None,
+ toBeChecked = False,
+ ):
+ """
+ Permet de définir un vecteur :
+ - asVector : entrée des données, comme un vecteur compatible avec le
+ constructeur de numpy.matrix, ou "True" si entrée par script.
+ - asPersistentVector : entrée des données, comme une série de vecteurs
+ compatible avec le constructeur de numpy.matrix, ou comme un objet de
+ type Persistence, ou "True" si entrée par script.
+ - asScript : si un script valide est donné contenant une variable
+ nommée "name", la variable est de type "asVector" (par défaut) ou
+ "asPersistentVector" selon que l'une de ces variables est placée à
+ "True".
+ - asDataFile : si un ou plusieurs fichiers valides sont donnés
+ contenant des valeurs en colonnes, elles-mêmes nommées "colNames"
+ (s'il n'y a pas de nom de colonne indiquée, on cherche une colonne
+ nommée "name"), on récupère les colonnes et on les range ligne après
+ ligne (colMajor=False, par défaut) ou colonne après colonne
+ (colMajor=True). La variable résultante est de type "asVector" (par
+ défaut) ou "asPersistentVector" selon que l'une de ces variables est
+ placée à "True".
+ """
+ self.__name = str(name)
+ self.__check = bool(toBeChecked)
+ #
+ self.__V = None
+ self.__T = None
+ self.__is_vector = False
+ self.__is_series = False
+ #
+ if asScript is not None:
+ __Vector, __Series = None, None
+ if asPersistentVector:
+ __Series = Interfaces.ImportFromScript(asScript).getvalue( self.__name )
+ else:
+ __Vector = Interfaces.ImportFromScript(asScript).getvalue( self.__name )
+ elif asDataFile is not None:
+ __Vector, __Series = None, None
+ if asPersistentVector:
+ if colNames is not None:
+ __Series = Interfaces.ImportFromFile(asDataFile).getvalue( colNames )[1]
+ else:
+ __Series = Interfaces.ImportFromFile(asDataFile).getvalue( [self.__name,] )[1]
+ if bool(colMajor) and not Interfaces.ImportFromFile(asDataFile).getformat() == "application/numpy.npz":
+ __Series = numpy.transpose(__Series)
+ elif not bool(colMajor) and Interfaces.ImportFromFile(asDataFile).getformat() == "application/numpy.npz":
+ __Series = numpy.transpose(__Series)
+ else:
+ if colNames is not None:
+ __Vector = Interfaces.ImportFromFile(asDataFile).getvalue( colNames )[1]
+ else:
+ __Vector = Interfaces.ImportFromFile(asDataFile).getvalue( [self.__name,] )[1]
+ if bool(colMajor):
+ __Vector = numpy.ravel(__Vector, order = "F")
+ else:
+ __Vector = numpy.ravel(__Vector, order = "C")
+ else:
+ __Vector, __Series = asVector, asPersistentVector
+ #
+ if __Vector is not None:
+ self.__is_vector = True
+ if isinstance(__Vector, str):
+ __Vector = PlatformInfo.strvect2liststr( __Vector )
+ self.__V = numpy.ravel(numpy.asarray( __Vector, dtype=float )).reshape((-1,1))
+ self.shape = self.__V.shape
+ self.size = self.__V.size
+ elif __Series is not None:
+ self.__is_series = True
+ if isinstance(__Series, (tuple, list, numpy.ndarray, numpy.matrix, str)):
+ #~ self.__V = Persistence.OneVector(self.__name, basetype=numpy.matrix)
+ self.__V = Persistence.OneVector(self.__name)
+ if isinstance(__Series, str):
+ __Series = PlatformInfo.strmatrix2liststr(__Series)
+ for member in __Series:
+ if isinstance(member, str):
+ member = PlatformInfo.strvect2liststr( member )
+ self.__V.store(numpy.asarray( member, dtype=float ))
+ else:
+ self.__V = __Series
+ if isinstance(self.__V.shape, (tuple, list)):
+ self.shape = self.__V.shape
+ else:
+ self.shape = self.__V.shape()
+ if len(self.shape) == 1:
+ self.shape = (self.shape[0],1)
+ self.size = self.shape[0] * self.shape[1]
+ else:
+ raise ValueError("The %s object is improperly defined or undefined, it requires at minima either a vector, a list/tuple of vectors or a persistent object. Please check your vector input."%self.__name)
+ #
+ if scheduledBy is not None:
+ self.__T = scheduledBy
+
+ def getO(self, withScheduler=False):
+ if withScheduler:
+ return self.__V, self.__T
+ elif self.__T is None:
+ return self.__V
+ else:
+ return self.__V
+
+ def isvector(self):
+ "Vérification du type interne"
+ return self.__is_vector
+
+ def isseries(self):
+ "Vérification du type interne"
+ return self.__is_series
+
+ def __repr__(self):
+ "x.__repr__() <==> repr(x)"
+ return repr(self.__V)
+
+ def __str__(self):
+ "x.__str__() <==> str(x)"
+ return str(self.__V)