Salome HOME
Minor documentation and code review corrections (38)
[modules/adao.git] / src / daComposant / daCore / Aidsm.py
index 28a515abdea542576d375589205a027e4034222e..256c38a765483378a4d8f87d6fc51793d6db9f2b 100644 (file)
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 #
-# Copyright (C) 2008-2020 EDF R&D
+# Copyright (C) 2008-2023 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
 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
 
 """
-    Normalized interface for ADAO scripting (generic API)
+    Normalized interface for ADAO scripting (generic API).
 """
 __author__ = "Jean-Philippe ARGAUD"
 __all__ = ["Aidsm"]
 
 import os
 import sys
+import inspect
 #
 from daCore.BasicObjects import State, Covariance, FullOperator, Operator
 from daCore.BasicObjects import AlgorithmAndParameters, DataObserver
@@ -42,7 +43,8 @@ import logging
 class Aidsm(object):
     """ ADAO Internal Data Structure Model """
     def __init__(self, name = "", addViewers=None):
-        self.__name = str(name)
+        self.__name         = str(name)
+        self.__objname      = None
         self.__directory    = None
         self.__case = CaseLogger(self.__name, "case", addViewers)
         #
@@ -76,6 +78,10 @@ class Aidsm(object):
             self.__adaoObject[ename] = None
         for ename in ("ObservationOperator", "EvolutionModel", "ControlModel"):
             self.__adaoObject[ename] = {}
+        for ename in ("BackgroundError", "ObservationError"):
+            self.__adaoObject[ename] = Covariance(ename, asEyeByScalar = 1.)
+        for ename in ("EvolutionError",):
+            self.__adaoObject[ename] = Covariance(ename, asEyeByScalar = 1.e-16)
         for ename in ("Observer", "UserPostAnalysis"):
             self.__adaoObject[ename]   = []
             self.__StoredInputs[ename] = [] # Vide par defaut
@@ -93,7 +99,6 @@ class Aidsm(object):
             Concept              = None, # Premier argument
             Algorithm            = None,
             AppliedInXb          = None,
-            AvoidRC              = True,
             Checked              = False,
             ColMajor             = False,
             ColNames             = None,
@@ -107,6 +112,7 @@ class Aidsm(object):
             ObjectMatrix         = None,
             OneFunction          = None,
             Parameters           = None,
+            PerformanceProfile   = None,
             ScalarSparseMatrix   = None,
             Scheduler            = None,
             Script               = None,
@@ -118,7 +124,7 @@ class Aidsm(object):
             Vector               = None,
             VectorSerie          = None,
             ):
-        "Interface unique de definition de variables d'entrees par argument"
+        "Interface unique de définition de variables d'entrées par argument"
         self.__case.register("set",dir(),locals(),None,True)
         try:
             if   Concept in ("Background", "CheckingPoint", "ControlInput", "Observation"):
@@ -150,20 +156,20 @@ class Aidsm(object):
                 self.setObservationOperator(
                     Matrix, OneFunction, ThreeFunctions, AppliedInXb,
                     Parameters, Script, ExtraArguments,
-                    Stored, AvoidRC, InputFunctionAsMulti, Checked )
+                    Stored, PerformanceProfile, InputFunctionAsMulti, Checked )
             elif Concept in ("EvolutionModel", "ControlModel"):
                 commande = getattr(self,"set"+Concept)
                 commande(
                     Matrix, OneFunction, ThreeFunctions,
                     Parameters, Script, Scheduler, ExtraArguments,
-                    Stored, AvoidRC, InputFunctionAsMulti, Checked )
+                    Stored, PerformanceProfile, InputFunctionAsMulti, Checked )
             else:
                 raise ValueError("the variable named '%s' is not allowed."%str(Concept))
         except Exception as e:
-            if isinstance(e, SyntaxError): msg = "at %s: %s"%(e.offset, e.text)
+            if isinstance(e, SyntaxError): msg = " at %s: %s"%(e.offset, e.text)
             else: msg = ""
             raise ValueError(("during settings, the following error occurs:\n"+\
-                              "\n%s %s\n\nSee also the potential messages, "+\
+                              "\n%s%s\n\nSee also the potential messages, "+\
                               "which can show the origin of the above error, "+\
                               "in the launching terminal.")%(str(e),msg))
 
@@ -179,7 +185,7 @@ class Aidsm(object):
             Stored         = False,
             Scheduler      = None,
             Checked        = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "Background"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = State(
@@ -207,7 +213,7 @@ class Aidsm(object):
             Stored         = False,
             Scheduler      = None,
             Checked        = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "CheckingPoint"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = State(
@@ -235,7 +241,7 @@ class Aidsm(object):
             Stored         = False,
             Scheduler      = None,
             Checked        = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "ControlInput"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = State(
@@ -263,7 +269,7 @@ class Aidsm(object):
             Stored         = False,
             Scheduler      = None,
             Checked        = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "Observation"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = State(
@@ -289,7 +295,7 @@ class Aidsm(object):
             Stored               = False,
             ObjectMatrix         = None,
             Checked              = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "BackgroundError"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = Covariance(
@@ -313,7 +319,7 @@ class Aidsm(object):
             Stored               = False,
             ObjectMatrix         = None,
             Checked              = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "ObservationError"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = Covariance(
@@ -337,7 +343,7 @@ class Aidsm(object):
             Stored               = False,
             ObjectMatrix         = None,
             Checked              = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "EvolutionError"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = Covariance(
@@ -362,10 +368,10 @@ class Aidsm(object):
             Script               = None,
             ExtraArguments       = None,
             Stored               = False,
-            AvoidRC              = True,
+            PerformanceProfile   = None,
             InputFunctionAsMulti = False,
             Checked              = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "ObservationOperator"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = FullOperator(
@@ -377,7 +383,7 @@ class Aidsm(object):
             asDict           = Parameters,
             appliedInX       = AppliedInXb,
             extraArguments   = ExtraArguments,
-            avoidRC          = AvoidRC,
+            performancePrf   = PerformanceProfile,
             inputAsMF        = InputFunctionAsMulti,
             scheduledBy      = None,
             toBeChecked      = Checked,
@@ -395,10 +401,10 @@ class Aidsm(object):
             Scheduler            = None,
             ExtraArguments       = None,
             Stored               = False,
-            AvoidRC              = True,
+            PerformanceProfile   = None,
             InputFunctionAsMulti = False,
             Checked              = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "EvolutionModel"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = FullOperator(
@@ -410,7 +416,7 @@ class Aidsm(object):
             asDict           = Parameters,
             appliedInX       = None,
             extraArguments   = ExtraArguments,
-            avoidRC          = AvoidRC,
+            performancePrf   = PerformanceProfile,
             inputAsMF        = InputFunctionAsMulti,
             scheduledBy      = Scheduler,
             toBeChecked      = Checked,
@@ -428,10 +434,10 @@ class Aidsm(object):
             Scheduler            = None,
             ExtraArguments       = None,
             Stored               = False,
-            AvoidRC              = True,
+            PerformanceProfile   = None,
             InputFunctionAsMulti = False,
             Checked              = False):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "ControlModel"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = FullOperator(
@@ -443,7 +449,7 @@ class Aidsm(object):
             asDict           = Parameters,
             appliedInX       = None,
             extraArguments   = ExtraArguments,
-            avoidRC          = AvoidRC,
+            performancePrf   = PerformanceProfile,
             inputAsMF        = InputFunctionAsMulti,
             scheduledBy      = Scheduler,
             toBeChecked      = Checked,
@@ -453,7 +459,7 @@ class Aidsm(object):
         return 0
 
     def setName(self, String=None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         self.__case.register("setName",dir(),locals())
         if String is not None:
             self.__name = str(String)
@@ -462,7 +468,7 @@ class Aidsm(object):
         self.__StoredInputs["Name"] = self.__name
 
     def setDirectory(self, String=None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         self.__case.register("setDirectory",dir(),locals())
         if os.path.isdir(os.path.abspath(str(String))):
             self.__directory = os.path.abspath(str(String))
@@ -492,7 +498,7 @@ class Aidsm(object):
             Algorithm  = None,
             Parameters = None,
             Script     = None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "AlgorithmParameters"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = AlgorithmAndParameters(
@@ -506,20 +512,22 @@ class Aidsm(object):
     def updateAlgorithmParameters(self,
             Parameters = None,
             Script     = None):
-        "Mise a jour d'un concept de calcul"
-        if "AlgorithmParameters" not in self.__adaoObject or self.__adaoObject["AlgorithmParameters"] is None:
+        "Mise à jour d'un concept de calcul"
+        Concept = "AlgorithmParameters"
+        if Concept not in self.__adaoObject or self.__adaoObject[Concept] is None:
             raise ValueError("\n\nNo algorithm registred, set one before updating parameters or executing\n")
-        self.__adaoObject["AlgorithmParameters"].updateParameters(
+        self.__adaoObject[Concept].updateParameters(
             asDict        = Parameters,
             asScript      = self.__with_directory(Script),
             )
+        # RaJ du register
         return 0
 
     def setRegulationParameters(self,
             Algorithm  = None,
             Parameters = None,
             Script     = None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "RegulationParameters"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = RegulationAndParameters(
@@ -533,7 +541,7 @@ class Aidsm(object):
     def setSupplementaryParameters(self,
             Parameters = None,
             Script     = None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "SupplementaryParameters"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept] = ExternalParameters(
@@ -546,7 +554,7 @@ class Aidsm(object):
     def updateSupplementaryParameters(self,
             Parameters = None,
             Script     = None):
-        "Mise a jour d'un concept de calcul"
+        "Mise à jour d'un concept de calcul"
         Concept = "SupplementaryParameters"
         if Concept not in self.__adaoObject or self.__adaoObject[Concept] is None:
             self.__adaoObject[Concept] = ExternalParameters(name = Concept)
@@ -564,7 +572,7 @@ class Aidsm(object):
             Info           = None,
             ObjectFunction = None,
             Scheduler      = None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "Observer"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept].append( DataObserver(
@@ -584,7 +592,7 @@ class Aidsm(object):
             Variable       = None,
             ObjectFunction = None,
             ):
-        "Permet de retirer un observer à une ou des variable nommée"
+        "Permet de retirer un observer à une ou des variable nommées"
         if "AlgorithmParameters" not in self.__adaoObject:
             raise ValueError("No algorithm registred, ask for one before removing observers")
         #
@@ -609,7 +617,7 @@ class Aidsm(object):
             Template       = None,
             String         = None,
             Script         = None):
-        "Definition d'un concept de calcul"
+        "Définition d'un concept de calcul"
         Concept = "UserPostAnalysis"
         self.__case.register("set"+Concept, dir(), locals())
         self.__adaoObject[Concept].append( repr(UserScript(
@@ -618,11 +626,12 @@ class Aidsm(object):
             asString    = String,
             asScript    = self.__with_directory(Script),
             )))
+        return 0
 
     # -----------------------------------------------------------
 
     def get(self, Concept=None, noDetails=True ):
-        "Recuperation d'une sortie du calcul"
+        "Récupération d'une sortie du calcul"
         if Concept is not None:
             try:
                 self.__case.register("get", dir(), locals(), Concept) # Break pickle in Python 2
@@ -667,7 +676,7 @@ class Aidsm(object):
 
     # -----------------------------------------------------------
 
-    def get_available_variables(self):
+    def __get_available_variables(self):
         """
         Renvoie les variables potentiellement utilisables pour l'étude,
         initialement stockées comme données d'entrées ou dans les algorithmes,
@@ -691,7 +700,7 @@ class Aidsm(object):
             variables.sort()
             return variables
 
-    def get_available_algorithms(self):
+    def __get_available_algorithms(self):
         """
         Renvoie la liste des algorithmes potentiellement utilisables, identifiés
         par les chaînes de caractères.
@@ -704,20 +713,20 @@ class Aidsm(object):
                     if os.path.isfile(os.path.join(trypath,fname)):
                         root, ext = os.path.splitext(fname)
                         if ext != ".py": continue
-                        fc = open(os.path.join(trypath,fname)).read()
-                        iselal = bool("class ElementaryAlgorithm" in fc)
-                        if iselal and ext == '.py' and root != '__init__':
-                            files.append(root)
+                        with open(os.path.join(trypath,fname)) as fc:
+                            iselal = bool("class ElementaryAlgorithm" in fc.read())
+                            if iselal and ext == '.py' and root != '__init__':
+                                files.append(root)
         files.sort()
         return files
 
-    def get_algorithms_main_path(self):
+    def __get_algorithms_main_path(self):
         """
         Renvoie le chemin pour le répertoire principal contenant les algorithmes
         """
         return self.__parent
 
-    def add_algorithms_path(self, Path=None):
+    def __add_algorithms_path(self, Path=None):
         """
         Ajoute au chemin de recherche des algorithmes un répertoire dans lequel
         se trouve un sous-répertoire "daAlgorithms"
@@ -757,6 +766,11 @@ class Aidsm(object):
         if FileName is not None:
             self.dump( FileName, "TUI")
         self.__adaoObject["AlgorithmParameters"].executePythonScheme( self.__adaoObject )
+        if "UserPostAnalysis" in self.__adaoObject and len(self.__adaoObject["UserPostAnalysis"])>0:
+            self.__objname = self.__retrieve_objname()
+            for __UpaOne in self.__adaoObject["UserPostAnalysis"]:
+                __UpaOne = eval(str(__UpaOne))
+                exec(__UpaOne, {}, {'self':self, 'ADD':self, 'case':self, 'adaopy':self, self.__objname:self})
         return 0
 
     def __executeYACSScheme(self, FileName=None):
@@ -779,7 +793,7 @@ class Aidsm(object):
         from numpy import array, matrix
         for __command in __commands:
             if (__command.find("set")>-1 and __command.find("set_")<0) or 'UserPostAnalysis' in __command:
-                exec("self."+__command)
+                exec("self."+__command, {}, locals())
             else:
                 self.__PostAnalysis.append(__command)
         return self
@@ -810,10 +824,28 @@ class Aidsm(object):
             __fullpath = __filename
         return __fullpath
 
+    def __retrieve_objname(self):
+        "Ne pas utiliser dans le __init__, la variable appelante n'existe pas encore"
+        __names  = []
+        for level in reversed(inspect.stack()):
+            __names += [name for name, value in level.frame.f_locals.items() if value is self]
+        __names += [name for name, value in globals().items() if value is self]
+        while 'self' in __names: __names.remove('self') # Devrait toujours être trouvé, donc pas d'erreur
+        if len(__names) > 0:
+            self.__objname = __names[0]
+        else:
+            self.__objname = "ADD"
+        return self.__objname
+
     def __dir__(self):
         "Clarifie la visibilité des méthodes"
         return ['set', 'get', 'execute', 'dump', 'load', '__doc__', '__init__', '__module__']
 
+    def __str__(self):
+        "Représentation pour impression (mais pas repr)"
+        msg  = self.dump(None, "SimpleReportInPlainTxt")
+        return msg
+
     def prepare_to_pickle(self):
         "Retire les variables non pickelisables, avec recopie efficace"
         if self.__adaoObject['AlgorithmParameters'] is not None: