Salome HOME
Code improvements, review and simplifications (2)
[modules/adao.git] / src / daComposant / daCore / Persistence.py
index c2bbd48c538e8d9744a1163c390bfd7b1c2ea7ec..f155146926ee0f3295cff795c97cbd168e91ebc0 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2008-2017 EDF R&D
+# Copyright (C) 2008-2022 EDF R&D
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
 
 """
 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
 
 """
-    Définit des outils de persistence et d'enregistrement de séries de valeurs
+    Définit des outils de persistance et d'enregistrement de séries de valeurs
     pour analyse ultérieure ou utilisation de calcul.
 """
 __author__ = "Jean-Philippe ARGAUD"
 __all__ = []
 
     pour analyse ultérieure ou utilisation de calcul.
 """
 __author__ = "Jean-Philippe ARGAUD"
 __all__ = []
 
-import sys, numpy, copy
+import os, numpy, copy, math
+import gzip, bz2, pickle
 
 from daCore.PlatformInfo import PathManagement ; PathManagement()
 
 from daCore.PlatformInfo import PathManagement ; PathManagement()
-
-if sys.version_info.major < 3:
-    range = xrange
-    iLong = long
-    import cPickle as pickle
-else:
-    iLong = int
-    import pickle
+from daCore.PlatformInfo import has_gnuplot, PlatformInfo
+mfp = PlatformInfo().MaximumPrecision()
+if has_gnuplot:
+    import Gnuplot
 
 # ==============================================================================
 class Persistence(object):
     """
 
 # ==============================================================================
 class Persistence(object):
     """
-    Classe générale de persistence définissant les accesseurs nécessaires
+    Classe générale de persistance définissant les accesseurs nécessaires
     (Template)
     """
     def __init__(self, name="", unit="", basetype=str):
     (Template)
     """
     def __init__(self, name="", unit="", basetype=str):
@@ -67,7 +64,6 @@ class Persistence(object):
         self.__tags     = []
         #
         self.__dynamic  = False
         self.__tags     = []
         #
         self.__dynamic  = False
-        self.__gnuplot  = None
         self.__g        = None
         self.__title    = None
         self.__ltitle   = None
         self.__g        = None
         self.__title    = None
         self.__ltitle   = None
@@ -101,7 +97,7 @@ class Persistence(object):
 
     def pop(self, item=None):
         """
 
     def pop(self, item=None):
         """
-        Retire une valeur enregistree par son index de stockage. Sans argument,
+        Retire une valeur enregistrée par son index de stockage. Sans argument,
         retire le dernier objet enregistre.
         """
         if item is not None:
         retire le dernier objet enregistre.
         """
         if item is not None:
@@ -143,6 +139,9 @@ class Persistence(object):
         "x.__len__() <==> len(x)"
         return len(self.__values)
 
         "x.__len__() <==> len(x)"
         return len(self.__values)
 
+    def name(self):
+        return self.__name
+
     def __getitem__(self, index=None ):
         "x.__getitem__(y) <==> x[y]"
         return copy.copy(self.__values[index])
     def __getitem__(self, index=None ):
         "x.__getitem__(y) <==> x[y]"
         return copy.copy(self.__values[index])
@@ -248,18 +247,18 @@ class Persistence(object):
                 return allKeys
 
     # ---------------------------------------------------------
                 return allKeys
 
     # ---------------------------------------------------------
-    # Pour compatibilite
+    # Pour compatibilité
     def stepnumber(self):
         "Nombre de pas"
         return len(self.__values)
 
     def stepnumber(self):
         "Nombre de pas"
         return len(self.__values)
 
-    # Pour compatibilite
+    # Pour compatibilité
     def stepserie(self, **kwargs):
         "Nombre de pas filtrés"
         __indexOfFilteredItems = self.__filteredIndexes(**kwargs)
         return __indexOfFilteredItems
 
     def stepserie(self, **kwargs):
         "Nombre de pas filtrés"
         __indexOfFilteredItems = self.__filteredIndexes(**kwargs)
         return __indexOfFilteredItems
 
-    # Pour compatibilite
+    # Pour compatibilité
     def steplist(self, **kwargs):
         "Nombre de pas filtrés"
         __indexOfFilteredItems = self.__filteredIndexes(**kwargs)
     def steplist(self, **kwargs):
         "Nombre de pas filtrés"
         __indexOfFilteredItems = self.__filteredIndexes(**kwargs)
@@ -273,7 +272,7 @@ class Persistence(object):
         élémentaires numpy.
         """
         try:
         élémentaires numpy.
         """
         try:
-            return [numpy.matrix(item).mean() for item in self.__values]
+            return [numpy.mean(item, dtype=mfp).astype('float') for item in self.__values]
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -288,9 +287,9 @@ class Persistence(object):
         """
         try:
             if numpy.version.version >= '1.1.0':
         """
         try:
             if numpy.version.version >= '1.1.0':
-                return [numpy.matrix(item).std(ddof=ddof) for item in self.__values]
+                return [numpy.array(item).std(ddof=ddof, dtype=mfp).astype('float') for item in self.__values]
             else:
             else:
-                return [numpy.matrix(item).std() for item in self.__values]
+                return [numpy.array(item).std(dtype=mfp).astype('float') for item in self.__values]
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -301,7 +300,7 @@ class Persistence(object):
         numpy.
         """
         try:
         numpy.
         """
         try:
-            return [numpy.matrix(item).sum() for item in self.__values]
+            return [numpy.array(item).sum() for item in self.__values]
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -312,7 +311,7 @@ class Persistence(object):
         numpy.
         """
         try:
         numpy.
         """
         try:
-            return [numpy.matrix(item).min() for item in self.__values]
+            return [numpy.array(item).min() for item in self.__values]
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -323,10 +322,112 @@ class Persistence(object):
         numpy.
         """
         try:
         numpy.
         """
         try:
-            return [numpy.matrix(item).max() for item in self.__values]
+            return [numpy.array(item).max() for item in self.__values]
+        except:
+            raise TypeError("Base type is incompatible with numpy")
+
+    def norms(self, _ord=None):
+        """
+        Norm (_ord : voir numpy.linalg.norm)
+
+        Renvoie la série, contenant à chaque pas, la norme des données au pas.
+        Il faut que le type de base soit compatible avec les types élémentaires
+        numpy.
+        """
+        try:
+            return [numpy.linalg.norm(item, _ord) for item in self.__values]
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
+    def maes(self, _predictor=None):
+        """
+        Mean Absolute Error (MAE)
+        mae(dX) = 1/n sum(dX_i)
+
+        Renvoie la série, contenant à chaque pas, la MAE des données au pas.
+        Il faut que le type de base soit compatible avec les types élémentaires
+        numpy. C'est réservé aux variables d'écarts ou d'incréments si le
+        prédicteur est None, sinon c'est appliqué à l'écart entre les données
+        au pas et le prédicteur au même pas.
+        """
+        if _predictor is None:
+            try:
+                return [numpy.mean(numpy.abs(item)) for item in self.__values]
+            except:
+                raise TypeError("Base type is incompatible with numpy")
+        else:
+            if len(_predictor) != len(self.__values):
+                raise ValueError("Predictor number of steps is incompatible with the values")
+            for i, item in enumerate(self.__values):
+                if numpy.asarray(_predictor[i]).size != numpy.asarray(item).size:
+                    raise ValueError("Predictor size at step %i is incompatible with the values"%i)
+            try:
+                return [numpy.mean(numpy.abs(numpy.ravel(item) - numpy.ravel(_predictor[i]))) for i, item in enumerate(self.__values)]
+            except:
+                raise TypeError("Base type is incompatible with numpy")
+
+    def mses(self, _predictor=None):
+        """
+        Mean-Square Error (MSE) ou Mean-Square Deviation (MSD)
+        mse(dX) = 1/n sum(dX_i**2)
+
+        Renvoie la série, contenant à chaque pas, la MSE des données au pas. Il
+        faut que le type de base soit compatible avec les types élémentaires
+        numpy. C'est réservé aux variables d'écarts ou d'incréments si le
+        prédicteur est None, sinon c'est appliqué à l'écart entre les données
+        au pas et le prédicteur au même pas.
+        """
+        if _predictor is None:
+            try:
+                __n = self.shape()[0]
+                return [(numpy.linalg.norm(item)**2 / __n) for item in self.__values]
+            except:
+                raise TypeError("Base type is incompatible with numpy")
+        else:
+            if len(_predictor) != len(self.__values):
+                raise ValueError("Predictor number of steps is incompatible with the values")
+            for i, item in enumerate(self.__values):
+                if numpy.asarray(_predictor[i]).size != numpy.asarray(item).size:
+                    raise ValueError("Predictor size at step %i is incompatible with the values"%i)
+            try:
+                __n = self.shape()[0]
+                return [(numpy.linalg.norm(numpy.ravel(item) - numpy.ravel(_predictor[i]))**2 / __n) for i, item in enumerate(self.__values)]
+            except:
+                raise TypeError("Base type is incompatible with numpy")
+
+    msds=mses # Mean-Square Deviation (MSD=MSE)
+
+    def rmses(self, _predictor=None):
+        """
+        Root-Mean-Square Error (RMSE) ou Root-Mean-Square Deviation (RMSD)
+        rmse(dX) = sqrt( 1/n sum(dX_i**2) ) = sqrt( mse(dX) )
+
+        Renvoie la série, contenant à chaque pas, la RMSE des données au pas.
+        Il faut que le type de base soit compatible avec les types élémentaires
+        numpy. C'est réservé aux variables d'écarts ou d'incréments si le
+        prédicteur est None, sinon c'est appliqué à l'écart entre les données
+        au pas et le prédicteur au même pas.
+        """
+        if _predictor is None:
+            try:
+                __n = self.shape()[0]
+                return [(numpy.linalg.norm(item) / math.sqrt(__n)) for item in self.__values]
+            except:
+                raise TypeError("Base type is incompatible with numpy")
+        else:
+            if len(_predictor) != len(self.__values):
+                raise ValueError("Predictor number of steps is incompatible with the values")
+            for i, item in enumerate(self.__values):
+                if numpy.asarray(_predictor[i]).size != numpy.asarray(item).size:
+                    raise ValueError("Predictor size at step %i is incompatible with the values"%i)
+            try:
+                __n = self.shape()[0]
+                return [(numpy.linalg.norm(numpy.ravel(item) - numpy.ravel(_predictor[i])) / math.sqrt(__n)) for i, item in enumerate(self.__values)]
+            except:
+                raise TypeError("Base type is incompatible with numpy")
+
+    rmsds = rmses # Root-Mean-Square Deviation (RMSD=RMSE)
+
     def __preplots(self,
                    title    = "",
                    xlabel   = "",
     def __preplots(self,
                    title    = "",
                    xlabel   = "",
@@ -339,21 +440,18 @@ class Persistence(object):
         "Préparation des plots"
         #
         # Vérification de la disponibilité du module Gnuplot
         "Préparation des plots"
         #
         # Vérification de la disponibilité du module Gnuplot
-        try:
-            import Gnuplot
-            self.__gnuplot = Gnuplot
-        except:
+        if not has_gnuplot:
             raise ImportError("The Gnuplot module is required to plot the object.")
         #
         # Vérification et compléments sur les paramètres d'entrée
         if persist:
             raise ImportError("The Gnuplot module is required to plot the object.")
         #
         # Vérification et compléments sur les paramètres d'entrée
         if persist:
-            self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -persist -geometry '+geometry
+            Gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -persist -geometry '+geometry
         else:
         else:
-            self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -geometry '+geometry
+            Gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -geometry '+geometry
         if ltitle is None:
             ltitle = ""
         if ltitle is None:
             ltitle = ""
-        self.__g = self.__gnuplot.Gnuplot() # persist=1
-        self.__g('set terminal '+self.__gnuplot.GnuplotOpts.default_term)
+        self.__g = Gnuplot.Gnuplot() # persist=1
+        self.__g('set terminal '+Gnuplot.GnuplotOpts.default_term)
         self.__g('set style data lines')
         self.__g('set grid')
         self.__g('set autoscale')
         self.__g('set style data lines')
         self.__g('set grid')
         self.__g('set autoscale')
@@ -412,7 +510,6 @@ class Persistence(object):
                          attendant un Return
                          Par défaut, pause = True
         """
                          attendant un Return
                          Par défaut, pause = True
         """
-        import os
         if not self.__dynamic:
             self.__preplots(title, xlabel, ylabel, ltitle, geometry, persist, pause )
             if dynamic:
         if not self.__dynamic:
             self.__preplots(title, xlabel, ylabel, ltitle, geometry, persist, pause )
             if dynamic:
@@ -436,7 +533,7 @@ class Persistence(object):
             else:
                 Steps = list(range(len(self.__values[index])))
             #
             else:
                 Steps = list(range(len(self.__values[index])))
             #
-            self.__g.plot( self.__gnuplot.Data( Steps, self.__values[index], title=ltitle ) )
+            self.__g.plot( Gnuplot.Data( Steps, self.__values[index], title=ltitle ) )
             #
             if filename != "":
                 i += 1
             #
             if filename != "":
                 i += 1
@@ -455,12 +552,13 @@ class Persistence(object):
         #
         self.__g('set title  "'+str(self.__title))
         Steps = list(range(len(self.__values)))
         #
         self.__g('set title  "'+str(self.__title))
         Steps = list(range(len(self.__values)))
-        self.__g.plot( self.__gnuplot.Data( Steps, self.__values, title=self.__ltitle ) )
+        self.__g.plot( Gnuplot.Data( Steps, self.__values, title=self.__ltitle ) )
         #
         if self.__pause:
             eval(input('Please press return to continue...\n'))
 
     # ---------------------------------------------------------
         #
         if self.__pause:
             eval(input('Please press return to continue...\n'))
 
     # ---------------------------------------------------------
+    # On pourrait aussi utiliser d'autres attributs d'un "array" comme "tofile"
     def mean(self):
         """
         Renvoie la moyenne sur toutes les valeurs sans tenir compte de la
     def mean(self):
         """
         Renvoie la moyenne sur toutes les valeurs sans tenir compte de la
@@ -468,10 +566,7 @@ class Persistence(object):
         les types élémentaires numpy.
         """
         try:
         les types élémentaires numpy.
         """
         try:
-            if self.__basetype in [int, float]:
-                return float( numpy.array(self.__values).mean() )
-            else:
-                return numpy.array(self.__values).mean(axis=0)
+            return numpy.mean(self.__values, axis=0, dtype=mfp).astype('float')
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -486,9 +581,9 @@ class Persistence(object):
         """
         try:
             if numpy.version.version >= '1.1.0':
         """
         try:
             if numpy.version.version >= '1.1.0':
-                return numpy.array(self.__values).std(ddof=ddof,axis=0)
+                return numpy.asarray(self.__values).std(ddof=ddof,axis=0).astype('float')
             else:
             else:
-                return numpy.array(self.__values).std(axis=0)
+                return numpy.asarray(self.__values).std(axis=0).astype('float')
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -499,7 +594,7 @@ class Persistence(object):
         les types élémentaires numpy.
         """
         try:
         les types élémentaires numpy.
         """
         try:
-            return numpy.array(self.__values).sum(axis=0)
+            return numpy.asarray(self.__values).sum(axis=0)
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -510,7 +605,7 @@ class Persistence(object):
         les types élémentaires numpy.
         """
         try:
         les types élémentaires numpy.
         """
         try:
-            return numpy.array(self.__values).min(axis=0)
+            return numpy.asarray(self.__values).min(axis=0)
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -521,7 +616,7 @@ class Persistence(object):
         les types élémentaires numpy.
         """
         try:
         les types élémentaires numpy.
         """
         try:
-            return numpy.array(self.__values).max(axis=0)
+            return numpy.asarray(self.__values).max(axis=0)
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
@@ -532,13 +627,10 @@ class Persistence(object):
         les types élémentaires numpy.
         """
         try:
         les types élémentaires numpy.
         """
         try:
-            return numpy.array(self.__values).cumsum(axis=0)
+            return numpy.asarray(self.__values).cumsum(axis=0)
         except:
             raise TypeError("Base type is incompatible with numpy")
 
         except:
             raise TypeError("Base type is incompatible with numpy")
 
-    # On pourrait aussi utiliser les autres attributs d'une "matrix", comme
-    # "tofile", "min"...
-
     def plot(self,
              steps    = None,
              title    = "",
     def plot(self,
              steps    = None,
              title    = "",
@@ -578,25 +670,22 @@ class Persistence(object):
         """
         #
         # Vérification de la disponibilité du module Gnuplot
         """
         #
         # Vérification de la disponibilité du module Gnuplot
-        try:
-            import Gnuplot
-            self.__gnuplot = Gnuplot
-        except:
+        if not has_gnuplot:
             raise ImportError("The Gnuplot module is required to plot the object.")
         #
         # Vérification et compléments sur les paramètres d'entrée
         if persist:
             raise ImportError("The Gnuplot module is required to plot the object.")
         #
         # Vérification et compléments sur les paramètres d'entrée
         if persist:
-            self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -persist -geometry '+geometry
+            Gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -persist -geometry '+geometry
         else:
         else:
-            self.__gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -geometry '+geometry
+            Gnuplot.GnuplotOpts.gnuplot_command = 'gnuplot -geometry '+geometry
         if ltitle is None:
             ltitle = ""
         if isinstance(steps,list) or isinstance(steps, numpy.ndarray):
             Steps = list(steps)
         else:
             Steps = list(range(len(self.__values[0])))
         if ltitle is None:
             ltitle = ""
         if isinstance(steps,list) or isinstance(steps, numpy.ndarray):
             Steps = list(steps)
         else:
             Steps = list(range(len(self.__values[0])))
-        self.__g = self.__gnuplot.Gnuplot() # persist=1
-        self.__g('set terminal '+self.__gnuplot.GnuplotOpts.default_term)
+        self.__g = Gnuplot.Gnuplot() # persist=1
+        self.__g('set terminal '+Gnuplot.GnuplotOpts.default_term)
         self.__g('set style data lines')
         self.__g('set grid')
         self.__g('set autoscale')
         self.__g('set style data lines')
         self.__g('set grid')
         self.__g('set autoscale')
@@ -606,9 +695,9 @@ class Persistence(object):
         #
         # Tracé du ou des vecteurs demandés
         indexes = list(range(len(self.__values)))
         #
         # Tracé du ou des vecteurs demandés
         indexes = list(range(len(self.__values)))
-        self.__g.plot( self.__gnuplot.Data( Steps, self.__values[indexes.pop(0)], title=ltitle+" (pas 0)" ) )
+        self.__g.plot( Gnuplot.Data( Steps, self.__values[indexes.pop(0)], title=ltitle+" (pas 0)" ) )
         for index in indexes:
         for index in indexes:
-            self.__g.replot( self.__gnuplot.Data( Steps, self.__values[index], title=ltitle+" (pas %i)"%index ) )
+            self.__g.replot( Gnuplot.Data( Steps, self.__values[index], title=ltitle+" (pas %i)"%index ) )
         #
         if filename != "":
             self.__g.hardcopy(filename=filename, color=1)
         #
         if filename != "":
             self.__g.hardcopy(filename=filename, color=1)
@@ -632,7 +721,7 @@ class Persistence(object):
         elif isinstance(Scheduler,range):  # Considéré comme un itérateur
             Schedulers = Scheduler
         elif isinstance(Scheduler,(list,tuple)):   # Considéré comme des index explicites
         elif isinstance(Scheduler,range):  # Considéré comme un itérateur
             Schedulers = Scheduler
         elif isinstance(Scheduler,(list,tuple)):   # Considéré comme des index explicites
-            Schedulers = [iLong(i) for i in Scheduler] # map( long, Scheduler )
+            Schedulers = [int(i) for i in Scheduler] # map( long, Scheduler )
         else:                              # Dans tous les autres cas, activé par défaut
             Schedulers = range( 0, maxiter )
         #
         else:                              # Dans tous les autres cas, activé par défaut
             Schedulers = range( 0, maxiter )
         #
@@ -670,6 +759,21 @@ class Persistence(object):
     def hasDataObserver(self):
         return bool(len(self.__dataobservers) > 0)
 
     def hasDataObserver(self):
         return bool(len(self.__dataobservers) > 0)
 
+# ==============================================================================
+class SchedulerTrigger(object):
+    """
+    Classe générale d'interface de type Scheduler/Trigger
+    """
+    def __init__(self,
+                 simplifiedCombo = None,
+                 startTime       = 0,
+                 endTime         = int( 1e9 ),
+                 timeDelay       = 1,
+                 timeUnit        = 1,
+                 frequency       = None,
+                ):
+        pass
+
 # ==============================================================================
 class OneScalar(Persistence):
     """
 # ==============================================================================
 class OneScalar(Persistence):
     """
@@ -701,15 +805,15 @@ class OneVector(Persistence):
 
 class OneMatrix(Persistence):
     """
 
 class OneMatrix(Persistence):
     """
-    Classe de stockage d'une matrice de valeurs (numpy.matrix) par pas.
+    Classe de stockage d'une matrice de valeurs homogènes par pas.
     """
     def __init__(self, name="", unit="", basetype = numpy.matrix):
         Persistence.__init__(self, name, unit, basetype)
 
 class OneList(Persistence):
     """
     """
     def __init__(self, name="", unit="", basetype = numpy.matrix):
         Persistence.__init__(self, name, unit, basetype)
 
 class OneList(Persistence):
     """
-    Classe de stockage d'une liste de valeurs hétérogènes (list) par pas. Ne pas
-    utiliser cette classe pour des données numériques homogènes, mais
+    Classe de stockage d'une liste de valeurs hétérogènes (list) par pas. Ne
+    pas utiliser cette classe pour des données numériques homogènes, mais
     "OneVector".
     """
     def __init__(self, name="", unit="", basetype = list):
     "OneVector".
     """
     def __init__(self, name="", unit="", basetype = list):
@@ -723,8 +827,8 @@ class OneNoType(Persistence):
     """
     Classe de stockage d'un objet sans modification (cast) de type. Attention,
     selon le véritable type de l'objet stocké à chaque pas, les opérations
     """
     Classe de stockage d'un objet sans modification (cast) de type. Attention,
     selon le véritable type de l'objet stocké à chaque pas, les opérations
-    arithmétiques à base de numpy peuvent être invalides ou donner des résultats
-    inattendus. Cette classe n'est donc à utiliser qu'à bon escient
+    arithmétiques à base de numpy peuvent être invalides ou donner des
+    résultats inattendus. Cette classe n'est donc à utiliser qu'à bon escient
     volontairement, et pas du tout par défaut.
     """
     def __init__(self, name="", unit="", basetype = NoType):
     volontairement, et pas du tout par défaut.
     """
     def __init__(self, name="", unit="", basetype = NoType):
@@ -743,9 +847,9 @@ class CompositePersistence(object):
         """
         name : nom courant
 
         """
         name : nom courant
 
-        La gestion interne des données est exclusivement basée sur les variables
-        initialisées ici (qui ne sont pas accessibles depuis l'extérieur des
-        objets comme des attributs) :
+        La gestion interne des données est exclusivement basée sur les
+        variables initialisées ici (qui ne sont pas accessibles depuis
+        l'extérieur des objets comme des attributs) :
         __StoredObjects : objets de type persistence collectés dans cet objet
         """
         self.__name = str(name)
         __StoredObjects : objets de type persistence collectés dans cet objet
         """
         self.__name = str(name)
@@ -781,8 +885,8 @@ class CompositePersistence(object):
 
     def add_object(self, name=None, persistenceType=Persistence, basetype=None ):
         """
 
     def add_object(self, name=None, persistenceType=Persistence, basetype=None ):
         """
-        Ajoute dans les objets stockables un nouvel objet défini par son nom, son
-        type de Persistence et son type de base à chaque pas.
+        Ajoute dans les objets stockables un nouvel objet défini par son nom,
+        son type de Persistence et son type de base à chaque pas.
         """
         if name is None: raise ValueError("Object name is required for adding an object.")
         if name in self.__StoredObjects.keys():
         """
         if name is None: raise ValueError("Object name is required for adding an object.")
         if name in self.__StoredObjects.keys():
@@ -865,7 +969,6 @@ class CompositePersistence(object):
         Enregistre l'objet dans le fichier indiqué selon le "mode" demandé,
         et renvoi le nom du fichier
         """
         Enregistre l'objet dans le fichier indiqué selon le "mode" demandé,
         et renvoi le nom du fichier
         """
-        import os
         if filename is None:
             if compress == "gzip":
                 filename = os.tempnam( os.getcwd(), 'dacp' ) + ".pkl.gz"
         if filename is None:
             if compress == "gzip":
                 filename = os.tempnam( os.getcwd(), 'dacp' ) + ".pkl.gz"
@@ -878,10 +981,8 @@ class CompositePersistence(object):
         #
         if mode == "pickle":
             if compress == "gzip":
         #
         if mode == "pickle":
             if compress == "gzip":
-                import gzip
                 output = gzip.open( filename, 'wb')
             elif compress == "bzip2":
                 output = gzip.open( filename, 'wb')
             elif compress == "bzip2":
-                import bz2
                 output = bz2.BZ2File( filename, 'wb')
             else:
                 output = open( filename, 'wb')
                 output = bz2.BZ2File( filename, 'wb')
             else:
                 output = open( filename, 'wb')
@@ -896,7 +997,6 @@ class CompositePersistence(object):
         """
         Recharge un objet composite sauvé en fichier
         """
         """
         Recharge un objet composite sauvé en fichier
         """
-        import os
         if filename is None:
             raise ValueError("A file name if requested to load a composite.")
         else:
         if filename is None:
             raise ValueError("A file name if requested to load a composite.")
         else:
@@ -904,10 +1004,8 @@ class CompositePersistence(object):
         #
         if mode == "pickle":
             if compress == "gzip":
         #
         if mode == "pickle":
             if compress == "gzip":
-                import gzip
                 pkl_file = gzip.open( filename, 'rb')
             elif compress == "bzip2":
                 pkl_file = gzip.open( filename, 'rb')
             elif compress == "bzip2":
-                import bz2
                 pkl_file = bz2.BZ2File( filename, 'rb')
             else:
                 pkl_file = open(filename, 'rb')
                 pkl_file = bz2.BZ2File( filename, 'rb')
             else:
                 pkl_file = open(filename, 'rb')
@@ -921,4 +1019,4 @@ class CompositePersistence(object):
 
 # ==============================================================================
 if __name__ == "__main__":
 
 # ==============================================================================
 if __name__ == "__main__":
-    print('\n AUTODIAGNOSTIC \n')
+    print('\n AUTODIAGNOSTIC\n')