X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FdaComposant%2FdaCore%2FAidsm.py;h=256c38a765483378a4d8f87d6fc51793d6db9f2b;hb=a6845547d27bcdc0928f898a4c8a2e4fc276c69e;hp=190b40cd62789eab3198580a9da07d964b904301;hpb=671c7e1161d628a4dd90aa1eae9188e02ac35835;p=modules%2Fadao.git diff --git a/src/daComposant/daCore/Aidsm.py b/src/daComposant/daCore/Aidsm.py index 190b40c..256c38a 100644 --- a/src/daComposant/daCore/Aidsm.py +++ b/src/daComposant/daCore/Aidsm.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright (C) 2008-2019 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 @@ -21,17 +21,19 @@ # 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 from daCore.BasicObjects import RegulationAndParameters, CaseLogger +from daCore.BasicObjects import UserScript, ExternalParameters from daCore import PlatformInfo # from daCore import ExtendedLogging ; ExtendedLogging.ExtendedLogging() # A importer en premier @@ -41,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) # @@ -49,33 +52,41 @@ class Aidsm(object): self.__StoredInputs = {} self.__PostAnalysis = [] # - self.__Concepts = [ + self.__Concepts = [ # Liste exhaustive "AlgorithmParameters", "Background", + "BackgroundError", "CheckingPoint", "ControlInput", - "Observation", - "BackgroundError", - "ObservationError", + "ControlModel", + "Debug", + "Directory", "EvolutionError", - "ObservationOperator", "EvolutionModel", - "ControlModel", "Name", - "Directory", - "Debug", "NoDebug", - "RegulationParameters", + "Observation", + "ObservationError", + "ObservationOperator", "Observer", + "RegulationParameters", + "SupplementaryParameters", + "UserPostAnalysis", ] # for ename in self.__Concepts: self.__adaoObject[ename] = None for ename in ("ObservationOperator", "EvolutionModel", "ControlModel"): self.__adaoObject[ename] = {} - for ename in ("Observer",): + 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] = [] + self.__StoredInputs[ename] = [] # Vide par defaut + self.__StoredInputs["Name"] = self.__name + self.__StoredInputs["Directory"] = self.__directory # # Récupère le chemin du répertoire parent et l'ajoute au path # (Cela complète l'action de la classe PathManagement dans PlatformInfo, @@ -88,7 +99,6 @@ class Aidsm(object): Concept = None, # Premier argument Algorithm = None, AppliedInXb = None, - AvoidRC = True, Checked = False, ColMajor = False, ColNames = None, @@ -102,6 +112,7 @@ class Aidsm(object): ObjectMatrix = None, OneFunction = None, Parameters = None, + PerformanceProfile = None, ScalarSparseMatrix = None, Scheduler = None, Script = None, @@ -113,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"): @@ -137,24 +148,28 @@ class Aidsm(object): self.setNoDebug() elif Concept == "Observer": self.setObserver( Variable, Template, String, Script, Info, ObjectFunction, Scheduler ) + elif Concept == "UserPostAnalysis": + self.setUserPostAnalysis( Template, String, Script ) + elif Concept == "SupplementaryParameters": + self.setSupplementaryParameters( Parameters, Script ) elif Concept == "ObservationOperator": 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)) @@ -170,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( @@ -198,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( @@ -226,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( @@ -254,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( @@ -280,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( @@ -304,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( @@ -328,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( @@ -353,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( @@ -368,7 +383,7 @@ class Aidsm(object): asDict = Parameters, appliedInX = AppliedInXb, extraArguments = ExtraArguments, - avoidRC = AvoidRC, + performancePrf = PerformanceProfile, inputAsMF = InputFunctionAsMulti, scheduledBy = None, toBeChecked = Checked, @@ -386,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( @@ -401,7 +416,7 @@ class Aidsm(object): asDict = Parameters, appliedInX = None, extraArguments = ExtraArguments, - avoidRC = AvoidRC, + performancePrf = PerformanceProfile, inputAsMF = InputFunctionAsMulti, scheduledBy = Scheduler, toBeChecked = Checked, @@ -419,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( @@ -434,7 +449,7 @@ class Aidsm(object): asDict = Parameters, appliedInX = None, extraArguments = ExtraArguments, - avoidRC = AvoidRC, + performancePrf = PerformanceProfile, inputAsMF = InputFunctionAsMulti, scheduledBy = Scheduler, toBeChecked = Checked, @@ -444,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) @@ -453,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)) @@ -483,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( @@ -497,27 +512,55 @@ class Aidsm(object): def updateAlgorithmParameters(self, Parameters = None, Script = None): - "Mise a jour d'un concept de calcul" - if "AlgorithmParameters" not in self.__adaoObject: - raise ValueError("No algorithm registred, ask for one before updating parameters") - self.__adaoObject["AlgorithmParameters"].updateParameters( + "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[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( - name = Concept, - asAlgorithm = Algorithm, - asDict = Parameters, - asScript = self.__with_directory(Script), + name = Concept, + asAlgorithm = Algorithm, + asDict = Parameters, + asScript = self.__with_directory(Script), + ) + return 0 + + def setSupplementaryParameters(self, + Parameters = None, + Script = None): + "Définition d'un concept de calcul" + Concept = "SupplementaryParameters" + self.__case.register("set"+Concept, dir(), locals()) + self.__adaoObject[Concept] = ExternalParameters( + name = Concept, + asDict = Parameters, + asScript = self.__with_directory(Script), + ) + return 0 + + def updateSupplementaryParameters(self, + Parameters = None, + Script = None): + "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) + self.__adaoObject[Concept].updateParameters( + asDict = Parameters, + asScript = self.__with_directory(Script), ) return 0 @@ -529,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( @@ -549,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") # @@ -570,10 +613,25 @@ class Aidsm(object): else: return self.__adaoObject["AlgorithmParameters"].removeObserver( ename, ObjectFunction ) + def setUserPostAnalysis(self, + Template = None, + String = None, + Script = None): + "Définition d'un concept de calcul" + Concept = "UserPostAnalysis" + self.__case.register("set"+Concept, dir(), locals()) + self.__adaoObject[Concept].append( repr(UserScript( + name = Concept, + asTemplate = Template, + 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 @@ -591,19 +649,34 @@ class Aidsm(object): elif Concept == "AlgorithmRequiredParameters" and self.__adaoObject["AlgorithmParameters"] is not None: return self.__adaoObject["AlgorithmParameters"].getAlgorithmRequiredParameters(noDetails) # + elif Concept == "AlgorithmRequiredInputs" and self.__adaoObject["AlgorithmParameters"] is not None: + return self.__adaoObject["AlgorithmParameters"].getAlgorithmInputArguments() + # + elif Concept == "AlgorithmAttributes" and self.__adaoObject["AlgorithmParameters"] is not None: + return self.__adaoObject["AlgorithmParameters"].getAlgorithmAttributes() + # + elif self.__adaoObject["SupplementaryParameters"] is not None and Concept == "SupplementaryParameters": + return self.__adaoObject["SupplementaryParameters"].get() + # + elif self.__adaoObject["SupplementaryParameters"] is not None and Concept in self.__adaoObject["SupplementaryParameters"]: + return self.__adaoObject["SupplementaryParameters"].get( Concept ) + # else: raise ValueError("The requested key \"%s\" does not exists as an input or a stored variable."%Concept) else: allvariables = {} allvariables.update( {"AlgorithmParameters":self.__adaoObject["AlgorithmParameters"].get()} ) + if self.__adaoObject["SupplementaryParameters"] is not None: + allvariables.update( {"SupplementaryParameters":self.__adaoObject["SupplementaryParameters"].get()} ) # allvariables.update( self.__adaoObject["AlgorithmParameters"].get() ) allvariables.update( self.__StoredInputs ) allvariables.pop('Observer', None) + allvariables.pop('UserPostAnalysis', None) return allvariables # ----------------------------------------------------------- - 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, @@ -617,13 +690,17 @@ class Aidsm(object): variables = [] if len(list(self.__adaoObject["AlgorithmParameters"].keys())) > 0: variables.extend(list(self.__adaoObject["AlgorithmParameters"].keys())) + if self.__adaoObject["SupplementaryParameters"] is not None and \ + len(list(self.__adaoObject["SupplementaryParameters"].keys())) > 0: + variables.extend(list(self.__adaoObject["SupplementaryParameters"].keys())) if len(list(self.__StoredInputs.keys())) > 0: variables.extend( list(self.__StoredInputs.keys()) ) variables.remove('Observer') + variables.remove('UserPostAnalysis') 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. @@ -636,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" @@ -666,10 +743,11 @@ class Aidsm(object): # ----------------------------------------------------------- - def execute(self, Executor=None, SaveCaseInFile=None): + def execute(self, Executor=None, SaveCaseInFile=None, nextStep=False): "Lancement du calcul" self.__case.register("execute",dir(),locals(),None,True) - Operator.CM.clearCache() + self.updateAlgorithmParameters(Parameters={"nextStep":bool(nextStep)}) + if not nextStep: Operator.CM.clearCache() try: if Executor == "YACS": self.__executeYACSScheme( SaveCaseInFile ) else: self.__executePythonScheme( SaveCaseInFile ) @@ -688,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): @@ -709,8 +792,8 @@ class Aidsm(object): __commands = self.__case.load(FileName, Content, Object, Formater) from numpy import array, matrix for __command in __commands: - if __command.find("set")>-1 and __command.find("set_")<0: - exec("self."+__command) + if (__command.find("set")>-1 and __command.find("set_")<0) or 'UserPostAnalysis' in __command: + exec("self."+__command, {}, locals()) else: self.__PostAnalysis.append(__command) return self @@ -741,17 +824,35 @@ 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: for k in self.__adaoObject['AlgorithmParameters'].keys(): if k == "Algorithm": continue if k in self.__StoredInputs: - raise ValueError("the key \"%s\s to be transfered for pickling will overwrite an existing one.") + raise ValueError("The key \"%s\" to be transfered for pickling will overwrite an existing one."%(k,)) if self.__adaoObject['AlgorithmParameters'].hasObserver( k ): self.__adaoObject['AlgorithmParameters'].removeObserver( k, "", True ) self.__StoredInputs[k] = self.__adaoObject['AlgorithmParameters'].pop(k, None)