Salome HOME
Documentation and source correction and improvements for DFO
[modules/adao.git] / src / daComposant / daCore / AssimilationStudy.py
index 87888d3702e757bbbd182de1a84154a16aba32d9..fe3233ef92b80eaa0c75193829151325f6c6d58c 100644 (file)
@@ -28,6 +28,7 @@
     les objets élémentaires de l'étude.
 """
 __author__ = "Jean-Philippe ARGAUD"
+__all__ = ["AssimilationStudy"]
 
 import os, sys
 import numpy
@@ -116,10 +117,7 @@ class AssimilationStudy:
           être rendue disponible au même titre que les variables de calcul
         """
         if asVector is not None:
-            if type( asVector ) is type( numpy.matrix([]) ):
-                self.__Xb = numpy.matrix( asVector.A1, numpy.float ).T
-            else:
-                self.__Xb = numpy.matrix( asVector,    numpy.float ).T
+            self.__Xb = numpy.matrix( numpy.ravel(numpy.matrix(asVector)), numpy.float ).T
         elif asPersistentVector is not None:
             if type(asPersistentVector) in [type([]),type(()),type(numpy.array([])),type(numpy.matrix([]))]:
                 self.__Xb = Persistence.OneVector("Background", basetype=numpy.matrix)
@@ -137,7 +135,9 @@ class AssimilationStudy:
             asCovariance  = None,
             asEyeByScalar = None,
             asEyeByVector = None,
+            asCovObject   = None,
             toBeStored    = False,
+            toBeChecked   = False,
             ):
         """
         Permet de définir la covariance des erreurs d'ébauche :
@@ -149,6 +149,8 @@ class AssimilationStudy:
         - asEyeByVector : entrée des données comme un seul vecteur de variance,
           à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
           n'étant donc explicitement à donner
+        - asCovObject : entrée des données comme un objet ayant des méthodes
+          particulieres de type matriciel
         - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
           être rendue disponible au même titre que les variables de calcul
         """
@@ -157,6 +159,8 @@ class AssimilationStudy:
             asCovariance  = asCovariance,
             asEyeByScalar = asEyeByScalar,
             asEyeByVector = asEyeByVector,
+            asCovObject   = asCovObject,
+            toBeChecked   = toBeChecked,
             )
         if toBeStored:
             self.__StoredInputs["BackgroundError"] = self.__B
@@ -180,10 +184,7 @@ class AssimilationStudy:
           être rendue disponible au même titre que les variables de calcul
         """
         if asVector is not None:
-            if type( asVector ) is type( numpy.matrix([]) ):
-                self.__Y = numpy.matrix( asVector.A1, numpy.float ).T
-            else:
-                self.__Y = numpy.matrix( asVector,    numpy.float ).T
+            self.__Y = numpy.matrix( numpy.ravel(numpy.matrix(asVector)), numpy.float ).T
         elif asPersistentVector is not None:
             if type(asPersistentVector) in [type([]),type(()),type(numpy.array([])),type(numpy.matrix([]))]:
                 self.__Y = Persistence.OneVector("Observation", basetype=numpy.matrix)
@@ -201,7 +202,9 @@ class AssimilationStudy:
             asCovariance  = None,
             asEyeByScalar = None,
             asEyeByVector = None,
+            asCovObject   = None,
             toBeStored    = False,
+            toBeChecked   = False,
             ):
         """
         Permet de définir la covariance des erreurs d'observations :
@@ -213,6 +216,8 @@ class AssimilationStudy:
         - asEyeByVector : entrée des données comme un seul vecteur de variance,
           à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
           n'étant donc explicitement à donner
+        - asCovObject : entrée des données comme un objet ayant des méthodes
+          particulieres de type matriciel
         - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
           être rendue disponible au même titre que les variables de calcul
         """
@@ -221,6 +226,8 @@ class AssimilationStudy:
             asCovariance  = asCovariance,
             asEyeByScalar = asEyeByScalar,
             asEyeByVector = asEyeByVector,
+            asCovObject   = asCovObject,
+            toBeChecked   = toBeChecked,
             )
         if toBeStored:
             self.__StoredInputs["ObservationError"] = self.__R
@@ -269,17 +276,17 @@ class AssimilationStudy:
                         "withmpWorkers"             :None,
                        }
         """
-        if (type(asFunction) is type({})) and \
-                asFunction.has_key("useApproximatedDerivatives") and bool(asFunction["useApproximatedDerivatives"]) and \
-                asFunction.has_key("Direct") and (asFunction["Direct"] is not None):
-            if not asFunction.has_key("withCenteredDF"):            asFunction["withCenteredDF"]            = False
-            if not asFunction.has_key("withIncrement"):             asFunction["withIncrement"]             = 0.01
-            if not asFunction.has_key("withdX"):                    asFunction["withdX"]                    = None
-            if not asFunction.has_key("withAvoidingRedundancy"):    asFunction["withAvoidingRedundancy"]    = True
-            if not asFunction.has_key("withToleranceInRedundancy"): asFunction["withToleranceInRedundancy"] = 1.e-18
-            if not asFunction.has_key("withLenghtOfRedundancy"):    asFunction["withLenghtOfRedundancy"]    = -1
-            if not asFunction.has_key("withmpEnabled"):             asFunction["withmpEnabled"]             = False
-            if not asFunction.has_key("withmpWorkers"):             asFunction["withmpWorkers"]             = None
+        if isinstance(asFunction, dict) and \
+                ("useApproximatedDerivatives" in asFunction) and bool(asFunction["useApproximatedDerivatives"]) and \
+                ("Direct" in asFunction) and (asFunction["Direct"] is not None):
+            if "withCenteredDF"            not in asFunction: asFunction["withCenteredDF"]            = False
+            if "withIncrement"             not in asFunction: asFunction["withIncrement"]             = 0.01
+            if "withdX"                    not in asFunction: asFunction["withdX"]                    = None
+            if "withAvoidingRedundancy"    not in asFunction: asFunction["withAvoidingRedundancy"]    = True
+            if "withToleranceInRedundancy" not in asFunction: asFunction["withToleranceInRedundancy"] = 1.e-18
+            if "withLenghtOfRedundancy"    not in asFunction: asFunction["withLenghtOfRedundancy"]    = -1
+            if "withmpEnabled"             not in asFunction: asFunction["withmpEnabled"]             = False
+            if "withmpWorkers"             not in asFunction: asFunction["withmpWorkers"]             = None
             from daNumerics.ApproximatedDerivatives import FDApproximation
             FDA = FDApproximation(
                 Function              = asFunction["Direct"],
@@ -295,13 +302,13 @@ class AssimilationStudy:
             self.__HO["Direct"]  = Operator( fromMethod = FDA.DirectOperator,  avoidingRedundancy = avoidRC )
             self.__HO["Tangent"] = Operator( fromMethod = FDA.TangentOperator, avoidingRedundancy = avoidRC )
             self.__HO["Adjoint"] = Operator( fromMethod = FDA.AdjointOperator, avoidingRedundancy = avoidRC )
-        elif (type(asFunction) is type({})) and \
-                asFunction.has_key("Tangent") and asFunction.has_key("Adjoint") and \
+        elif isinstance(asFunction, dict) and \
+                ("Tangent" in asFunction) and ("Adjoint" in asFunction) and \
                 (asFunction["Tangent"] is not None) and (asFunction["Adjoint"] is not None):
-            if not asFunction.has_key("Direct") or (asFunction["Direct"] is None):
+            if ("Direct" not in asFunction) or (asFunction["Direct"] is None):
                 self.__HO["Direct"] = Operator( fromMethod = asFunction["Tangent"], avoidingRedundancy = avoidRC )
             else:
-                self.__HO["Direct"] = Operator( fromMethod = asFunction["Direct"],  avoidingRedundancy = avoidRC  )
+                self.__HO["Direct"] = Operator( fromMethod = asFunction["Direct"],  avoidingRedundancy = avoidRC )
             self.__HO["Tangent"]    = Operator( fromMethod = asFunction["Tangent"], avoidingRedundancy = avoidRC )
             self.__HO["Adjoint"]    = Operator( fromMethod = asFunction["Adjoint"], avoidingRedundancy = avoidRC )
         elif asMatrix is not None:
@@ -373,17 +380,17 @@ class AssimilationStudy:
                         "withmpWorkers"             :None,
                        }
         """
-        if (type(asFunction) is type({})) and \
-                asFunction.has_key("useApproximatedDerivatives") and bool(asFunction["useApproximatedDerivatives"]) and \
-                asFunction.has_key("Direct") and (asFunction["Direct"] is not None):
-            if not asFunction.has_key("withCenteredDF"):            asFunction["withCenteredDF"]            = False
-            if not asFunction.has_key("withIncrement"):             asFunction["withIncrement"]             = 0.01
-            if not asFunction.has_key("withdX"):                    asFunction["withdX"]                    = None
-            if not asFunction.has_key("withAvoidingRedundancy"):    asFunction["withAvoidingRedundancy"]    = True
-            if not asFunction.has_key("withToleranceInRedundancy"): asFunction["withToleranceInRedundancy"] = 1.e-18
-            if not asFunction.has_key("withLenghtOfRedundancy"):    asFunction["withLenghtOfRedundancy"]    = -1
-            if not asFunction.has_key("withmpEnabled"):             asFunction["withmpEnabled"]             = False
-            if not asFunction.has_key("withmpWorkers"):             asFunction["withmpWorkers"]             = None
+        if isinstance(asFunction, dict) and \
+                ("useApproximatedDerivatives" in asFunction) and bool(asFunction["useApproximatedDerivatives"]) and \
+                ("Direct" in asFunction) and (asFunction["Direct"] is not None):
+            if "withCenteredDF"            not in asFunction: asFunction["withCenteredDF"]            = False
+            if "withIncrement"             not in asFunction: asFunction["withIncrement"]             = 0.01
+            if "withdX"                    not in asFunction: asFunction["withdX"]                    = None
+            if "withAvoidingRedundancy"    not in asFunction: asFunction["withAvoidingRedundancy"]    = True
+            if "withToleranceInRedundancy" not in asFunction: asFunction["withToleranceInRedundancy"] = 1.e-18
+            if "withLenghtOfRedundancy"    not in asFunction: asFunction["withLenghtOfRedundancy"]    = -1
+            if "withmpEnabled"             not in asFunction: asFunction["withmpEnabled"]             = False
+            if "withmpWorkers"             not in asFunction: asFunction["withmpWorkers"]             = None
             from daNumerics.ApproximatedDerivatives import FDApproximation
             FDA = FDApproximation(
                 Function              = asFunction["Direct"],
@@ -396,13 +403,13 @@ class AssimilationStudy:
                 mpEnabled             = asFunction["withmpEnabled"],
                 mpWorkers             = asFunction["withmpWorkers"],
                 )
-            self.__EM["Direct"]  = Operator( fromMethod = FDA.DirectOperator,  avoidingRedundancy = avoidRC  )
+            self.__EM["Direct"]  = Operator( fromMethod = FDA.DirectOperator,  avoidingRedundancy = avoidRC )
             self.__EM["Tangent"] = Operator( fromMethod = FDA.TangentOperator, avoidingRedundancy = avoidRC )
             self.__EM["Adjoint"] = Operator( fromMethod = FDA.AdjointOperator, avoidingRedundancy = avoidRC )
-        elif (type(asFunction) is type({})) and \
-                asFunction.has_key("Tangent") and asFunction.has_key("Adjoint") and \
+        elif isinstance(asFunction, dict) and \
+                ("Tangent" in asFunction) and ("Adjoint" in asFunction) and \
                 (asFunction["Tangent"] is not None) and (asFunction["Adjoint"] is not None):
-            if not asFunction.has_key("Direct") or (asFunction["Direct"] is None):
+            if ("Direct" not in asFunction) or (asFunction["Direct"] is None):
                 self.__EM["Direct"] = Operator( fromMethod = asFunction["Tangent"], avoidingRedundancy = avoidRC )
             else:
                 self.__EM["Direct"] = Operator( fromMethod = asFunction["Direct"],  avoidingRedundancy = avoidRC )
@@ -425,7 +432,9 @@ class AssimilationStudy:
             asCovariance  = None,
             asEyeByScalar = None,
             asEyeByVector = None,
+            asCovObject   = None,
             toBeStored    = False,
+            toBeChecked   = False,
             ):
         """
         Permet de définir la covariance des erreurs de modèle :
@@ -437,6 +446,8 @@ class AssimilationStudy:
         - asEyeByVector : entrée des données comme un seul vecteur de variance,
           à mettre sur la diagonale d'une matrice de corrélation, aucune matrice
           n'étant donc explicitement à donner
+        - asCovObject : entrée des données comme un objet ayant des méthodes
+          particulieres de type matriciel
         - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
           être rendue disponible au même titre que les variables de calcul
         """
@@ -445,6 +456,8 @@ class AssimilationStudy:
             asCovariance  = asCovariance,
             asEyeByScalar = asEyeByScalar,
             asEyeByVector = asEyeByVector,
+            asCovObject   = asCovObject,
+            toBeChecked   = toBeChecked,
             )
         if toBeStored:
             self.__StoredInputs["EvolutionError"] = self.__Q
@@ -481,29 +494,53 @@ class AssimilationStudy:
           constructeur de numpy.matrix.
         - toBeStored : booléen indiquant si la donnée d'entrée est sauvée pour
           être rendue disponible au même titre que les variables de calcul
+        L'argument "asFunction" peut prendre la forme complète suivante, avec
+        les valeurs par défaut standards :
+          asFunction = {"Direct":None, "Tangent":None, "Adjoint":None,
+                        "useApproximatedDerivatives":False,
+                        "withCenteredDF"            :False,
+                        "withIncrement"             :0.01,
+                        "withdX"                    :None,
+                        "withAvoidingRedundancy"    :True,
+                        "withToleranceInRedundancy" :1.e-18,
+                        "withLenghtOfRedundancy"    :-1,
+                        "withmpEnabled"             :False,
+                        "withmpWorkers"             :None,
+                       }
         """
-        if (type(asFunction) is type({})) and \
-                asFunction.has_key("useApproximatedDerivatives") and bool(asFunction["useApproximatedDerivatives"]) and \
-                asFunction.has_key("Direct") and (asFunction["Direct"] is not None):
-            if not asFunction.has_key("withCenteredDF"): asFunction["withCenteredDF"] = False
-            if not asFunction.has_key("withIncrement"):  asFunction["withIncrement"]  = 0.01
-            if not asFunction.has_key("withdX"):         asFunction["withdX"]         = None
+        if isinstance(asFunction, dict) and \
+                ("useApproximatedDerivatives" in asFunction) and bool(asFunction["useApproximatedDerivatives"]) and \
+                ("Direct" in asFunction) and (asFunction["Direct"] is not None):
+            if "withCenteredDF"            not in asFunction: asFunction["withCenteredDF"]            = False
+            if "withIncrement"             not in asFunction: asFunction["withIncrement"]             = 0.01
+            if "withdX"                    not in asFunction: asFunction["withdX"]                    = None
+            if "withAvoidingRedundancy"    not in asFunction: asFunction["withAvoidingRedundancy"]    = True
+            if "withToleranceInRedundancy" not in asFunction: asFunction["withToleranceInRedundancy"] = 1.e-18
+            if "withLenghtOfRedundancy"    not in asFunction: asFunction["withLenghtOfRedundancy"]    = -1
+            if "withmpEnabled"             not in asFunction: asFunction["withmpEnabled"]             = False
+            if "withmpWorkers"             not in asFunction: asFunction["withmpWorkers"]             = None
             from daNumerics.ApproximatedDerivatives import FDApproximation
             FDA = FDApproximation(
-                Function   = asFunction["Direct"],
-                centeredDF = asFunction["withCenteredDF"],
-                increment  = asFunction["withIncrement"],
-                dX         = asFunction["withdX"] )
-            self.__CM["Direct"]  = Operator( fromMethod = FDA.DirectOperator,  avoidingRedundancy = avoidRC  )
+                Function              = asFunction["Direct"],
+                centeredDF            = asFunction["withCenteredDF"],
+                increment             = asFunction["withIncrement"],
+                dX                    = asFunction["withdX"],
+                avoidingRedundancy    = asFunction["withAvoidingRedundancy"],
+                toleranceInRedundancy = asFunction["withToleranceInRedundancy"],
+                lenghtOfRedundancy    = asFunction["withLenghtOfRedundancy"],
+                mpEnabled             = asFunction["withmpEnabled"],
+                mpWorkers             = asFunction["withmpWorkers"],
+                )
+            self.__CM["Direct"]  = Operator( fromMethod = FDA.DirectOperator,  avoidingRedundancy = avoidRC )
             self.__CM["Tangent"] = Operator( fromMethod = FDA.TangentOperator, avoidingRedundancy = avoidRC )
             self.__CM["Adjoint"] = Operator( fromMethod = FDA.AdjointOperator, avoidingRedundancy = avoidRC )
-        elif (type(asFunction) is type({})) and \
-                asFunction.has_key("Tangent") and asFunction.has_key("Adjoint") and \
+        elif isinstance(asFunction, dict) and \
+                ("Tangent" in asFunction) and ("Adjoint" in asFunction) and \
                 (asFunction["Tangent"] is not None) and (asFunction["Adjoint"] is not None):
-            if not asFunction.has_key("Direct") or (asFunction["Direct"] is None):
+            if ("Direct" not in asFunction) or (asFunction["Direct"] is None):
                 self.__CM["Direct"] = Operator( fromMethod = asFunction["Tangent"], avoidingRedundancy = avoidRC )
             else:
-                self.__CM["Direct"] = Operator( fromMethod = asFunction["Direct"],  avoidingRedundancy = avoidRC  )
+                self.__CM["Direct"] = Operator( fromMethod = asFunction["Direct"],  avoidingRedundancy = avoidRC )
             self.__CM["Tangent"]    = Operator( fromMethod = asFunction["Tangent"], avoidingRedundancy = avoidRC )
             self.__CM["Adjoint"]    = Operator( fromMethod = asFunction["Adjoint"], avoidingRedundancy = avoidRC )
         elif asMatrix is not None:
@@ -536,10 +573,7 @@ class AssimilationStudy:
           être rendue disponible au même titre que les variables de calcul
         """
         if asVector is not None:
-            if isinstance(asVector,numpy.matrix):
-                self.__U = numpy.matrix( asVector.A1, numpy.float ).T
-            else:
-                self.__U = numpy.matrix( asVector,    numpy.float ).T
+            self.__U = numpy.matrix( numpy.ravel(numpy.matrix(asVector)), numpy.float ).T
         elif asPersistentVector is not None:
             if type(asPersistentVector) in [type([]),type(()),type(numpy.array([])),type(numpy.matrix([]))]:
                 self.__U = Persistence.OneVector("ControlInput", basetype=numpy.matrix)
@@ -659,9 +693,9 @@ class AssimilationStudy:
         #
         # Instancie un objet du type élémentaire du fichier
         # -------------------------------------------------
-        if self.__StoredInputs.has_key(name):
+        if name in self.__StoredInputs:
             raise ValueError("A default input with the same name \"%s\" already exists."%str(name))
-        elif self.__StoredDiagnostics.has_key(name):
+        elif name in self.__StoredDiagnostics:
             raise ValueError("A diagnostic with the same name \"%s\" already exists."%str(name))
         else:
             self.__StoredDiagnostics[name] = self.__diagnosticFile.ElementaryDiagnostic(
@@ -677,64 +711,64 @@ class AssimilationStudy:
         Validation de la correspondance correcte des tailles des variables et
         des matrices s'il y en a.
         """
-        if self.__Xb is None:                  __Xb_shape = (0,)
-        elif hasattr(self.__Xb,"size"):        __Xb_shape = (self.__Xb.size,)
+        if self.__Xb is None:                      __Xb_shape = (0,)
+        elif hasattr(self.__Xb,"size"):            __Xb_shape = (self.__Xb.size,)
         elif hasattr(self.__Xb,"shape"):
-            if type(self.__Xb.shape) is tuple: __Xb_shape = self.__Xb.shape
-            else:                              __Xb_shape = 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,)
+        if self.__Y is None:                       __Y_shape = (0,)
+        elif hasattr(self.__Y,"size"):             __Y_shape = (self.__Y.size,)
         elif hasattr(self.__Y,"shape"):
-            if type(self.__Y.shape) is tuple: __Y_shape = self.__Y.shape
-            else:                             __Y_shape = 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,)
+        if self.__U is None:                       __U_shape = (0,)
+        elif hasattr(self.__U,"size"):             __U_shape = (self.__U.size,)
         elif hasattr(self.__U,"shape"):
-            if type(self.__U.shape) is tuple: __U_shape = self.__U.shape
-            else:                             __U_shape = 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)
+        if self.__B is None:                       __B_shape = (0,0)
         elif hasattr(self.__B,"shape"):
-            if type(self.__B.shape) is tuple: __B_shape = self.__B.shape
-            else:                             __B_shape = 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)
+        if self.__R is None:                       __R_shape = (0,0)
         elif hasattr(self.__R,"shape"):
-            if type(self.__R.shape) is tuple: __R_shape = self.__R.shape
-            else:                             __R_shape = 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)
+        if self.__Q is None:                       __Q_shape = (0,0)
         elif hasattr(self.__Q,"shape"):
-            if type(self.__Q.shape) is tuple: __Q_shape = self.__Q.shape
-            else:                             __Q_shape = 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 type(self.__HO) is type({}):                __HO_shape = (0,0)
+        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 type(self.__HO["Direct"].shape) is tuple: __HO_shape = self.__HO["Direct"].shape
-            else:                                        __HO_shape = 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 type(self.__EM) is type({}):                __EM_shape = (0,0)
+        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 type(self.__EM["Direct"].shape) is tuple: __EM_shape = self.__EM["Direct"].shape
-            else:                                        __EM_shape = 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 type(self.__CM) is type({}):                __CM_shape = (0,0)
+        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 type(self.__CM["Direct"].shape) is tuple: __CM_shape = self.__CM["Direct"].shape
-            else:                                        __CM_shape = 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
@@ -781,9 +815,9 @@ class AssimilationStudy:
         if self.__CM is not None and len(self.__CM) > 0 and not(type(self.__CM) is type({})) 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 self.__StoredInputs.has_key("AlgorithmParameters") \
-            and self.__StoredInputs["AlgorithmParameters"].has_key("Bounds") \
-            and (type(self.__StoredInputs["AlgorithmParameters"]["Bounds"]) is type([]) or type(self.__StoredInputs["AlgorithmParameters"]["Bounds"]) is type(())) \
+        if ("AlgorithmParameters" in self.__StoredInputs) \
+            and ("Bounds" in self.__StoredInputs["AlgorithmParameters"]) \
+            and (isinstance(self.__StoredInputs["AlgorithmParameters"]["Bounds"], list) or isinstance(self.__StoredInputs["AlgorithmParameters"]["Bounds"], tuple)) \
             and (len(self.__StoredInputs["AlgorithmParameters"]["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.__StoredInputs["AlgorithmParameters"]["Bounds"]),max(__Xb_shape)))
@@ -826,11 +860,11 @@ class AssimilationStudy:
         stockée qui est renvoyée, et le diagnostic est inatteignable.
         """
         if key is not None:
-            if self.__algorithm.has_key(key):
+            if key in self.__algorithm:
                 return self.__algorithm.get( key )
-            elif self.__StoredInputs.has_key(key):
+            elif key in self.__StoredInputs:
                 return self.__StoredInputs[key]
-            elif self.__StoredDiagnostics.has_key(key):
+            elif key in self.__StoredDiagnostics:
                 return self.__StoredDiagnostics[key]
             else:
                 raise ValueError("The requested key \"%s\" does not exists as an input, a diagnostic or a stored variable."%key)
@@ -953,14 +987,14 @@ class AssimilationStudy:
         les arguments (variable persistante VariableName, paramètres HookParameters).
         """
         #
-        if type( self.__algorithm ) is dict:
+        if isinstance(self.__algorithm, dict):
             raise ValueError("No observer can be build before choosing an algorithm.")
         #
         # Vérification du nom de variable et typage
         # -----------------------------------------
-        if type( VariableName ) is str:
+        if isinstance(VariableName, str):
             VariableNames = [VariableName,]
-        elif type( VariableName ) is list:
+        elif isinstance(VariableName, list):
             VariableNames = map( str, VariableName )
         else:
             raise ValueError("The observer requires a name or a list of names of variables.")
@@ -968,7 +1002,7 @@ class AssimilationStudy:
         # Association interne de l'observer à la variable
         # -----------------------------------------------
         for n in VariableNames:
-            if not self.__algorithm.has_key( n ):
+            if n not in self.__algorithm:
                 raise ValueError("An observer requires to be set on a variable named %s which does not exist."%n)
             else:
                 self.__algorithm.StoredVariables[ n ].setDataObserver(
@@ -985,14 +1019,14 @@ class AssimilationStudy:
         Permet de retirer un observer à une ou des variable nommée.
         """
         #
-        if type( self.__algorithm ) is dict:
+        if isinstance(self.__algorithm, dict):
             raise ValueError("No observer can be removed before choosing an algorithm.")
         #
         # Vérification du nom de variable et typage
         # -----------------------------------------
-        if type( VariableName ) is str:
+        if isinstance(VariableName, str):
             VariableNames = [VariableName,]
-        elif type( VariableName ) is list:
+        elif isinstance(VariableName, list):
             VariableNames = map( str, VariableName )
         else:
             raise ValueError("The observer requires a name or a list of names of variables.")
@@ -1000,7 +1034,7 @@ class AssimilationStudy:
         # Association interne de l'observer à la variable
         # -----------------------------------------------
         for n in VariableNames:
-            if not self.__algorithm.has_key( n ):
+            if n not in self.__algorithm:
                 raise ValueError("An observer requires to be removed on a variable named %s which does not exist."%n)
             else:
                 self.__algorithm.StoredVariables[ n ].removeDataObserver(