X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FdaComposant%2FdaCore%2FAidsm.py;h=3aa0c20e835bb64958b4f7425609d10f8971fa9b;hb=61f19963a2e2ed620bdf577c5a01808586dd938d;hp=472bcb38f461b2cfee7cd2c0f349a090c6117dbd;hpb=152ca2f3c50fdc364491654bf2dae067a4dbd7db;p=modules%2Fadao.git diff --git a/src/daComposant/daCore/Aidsm.py b/src/daComposant/daCore/Aidsm.py index 472bcb3..3aa0c20 100644 --- a/src/daComposant/daCore/Aidsm.py +++ b/src/daComposant/daCore/Aidsm.py @@ -1,6 +1,6 @@ # -*- 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 @@ -21,237 +21,72 @@ # 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, sys -from daCore import ExtendedLogging ; ExtendedLogging.ExtendedLogging() # A importer en premier -import logging -import numpy +import os +import sys +import inspect # from daCore.BasicObjects import State, Covariance, FullOperator, Operator from daCore.BasicObjects import AlgorithmAndParameters, DataObserver -from daCore.BasicObjects import DiagnosticAndParameters, ImportFromScript -from daCore.BasicObjects import CaseLogger, GenericCaseViewer -from daCore.Templates import ObserverTemplates -from daCore import Persistence +from daCore.BasicObjects import RegulationAndParameters, CaseLogger +from daCore.BasicObjects import UserScript, ExternalParameters from daCore import PlatformInfo - -# ============================================================================== -class DICViewer(GenericCaseViewer): - """ - Etablissement des commandes de creation d'un cas DIC - """ - def __init__(self, __name="", __objname="case", __content=None): - "Initialisation et enregistrement de l'entete" - GenericCaseViewer.__init__(self, __name, __objname, __content) - self._addLine("# -*- coding: utf-8 -*-") - self._addLine("#\n# Input for ADAO converter to YACS\n#") - self._addLine("from numpy import array, matrix") - self._addLine("#") - self._addLine("study_config = {}") - self._addLine("study_config['StudyType'] = 'ASSIMILATION_STUDY'") - self._addLine("study_config['Name'] = '%s'"%self._name) - self._addLine("observers = {}") - self._addLine("study_config['Observers'] = observers") - self._addLine("#") - self._addLine("inputvariables_config = {}") - self._addLine("inputvariables_config['Order'] =['adao_default']") - self._addLine("inputvariables_config['adao_default'] = -1") - self._addLine("study_config['InputVariables'] = inputvariables_config") - self._addLine("#") - self._addLine("outputvariables_config = {}") - self._addLine("outputvariables_config['Order'] = ['adao_default']") - self._addLine("outputvariables_config['adao_default'] = -1") - self._addLine("study_config['OutputVariables'] = outputvariables_config") - if __content is not None: - for command in __content: - self._append(*command) - def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False): - "Transformation d'une commande individuelle en un enregistrement" - if __command == "set": __command = __local["Concept"] - else: __command = __command.replace("set", "", 1) - # - __text = None - if __command in (None, 'execute', 'executePythonScheme', 'executeYACSScheme', 'get'): - return - elif __command in ['Debug', 'setDebug']: - __text = "#\nstudy_config['Debug'] = '1'" - elif __command in ['NoDebug', 'setNoDebug']: - __text = "#\nstudy_config['Debug'] = '0'" - elif __command in ['Observer', 'setObserver']: - __obs = __local['Variable'] - self._numobservers += 1 - __text = "#\n" - __text += "observers['%s'] = {}\n"%__obs - if __local['String'] is not None: - __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String') - __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, __local['String']) - if __local['Script'] is not None: - __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'Script') - __text += "observers['%s']['Script'] = \"%s\"\n"%(__obs, __local['Script']) - if __local['Template'] is not None: - __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String') - __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, ObserverTemplates[__local['Template']]) - if __local['Info'] is not None: - __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __local['Info']) - else: - __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __obs) - __text += "observers['%s']['number'] = %s"%(__obs, self._numobservers) - elif __local is not None: # __keys is not None and - numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15) - __text = "#\n" - __text += "%s_config = {}\n"%__command - if 'self' in __local: __local.pop('self') - __to_be_removed = [] - for __k,__v in __local.items(): - if __v is None: __to_be_removed.append(__k) - for __k in __to_be_removed: - __local.pop(__k) - for __k,__v in __local.items(): - if __k == "Concept": continue - if __k in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix','OneFunction','ThreeFunctions'] and 'Script' in __local: continue - if __k == 'Algorithm': - __text += "study_config['Algorithm'] = %s\n"%(repr(__v)) - elif __k == 'Script': - __k = 'Vector' - __f = 'Script' - __v = "'"+repr(__v)+"'" - for __lk in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix']: - if __lk in __local and __local[__lk]: __k = __lk - if __command == "AlgorithmParameters": __k = "Dict" - if 'OneFunction' in __local and __local['OneFunction']: - __text += "%s_ScriptWithOneFunction = {}\n"%(__command,) - __text += "%s_ScriptWithOneFunction['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,) - __text += "%s_ScriptWithOneFunction['Script'] = {}\n"%(__command,) - __text += "%s_ScriptWithOneFunction['Script']['Direct'] = %s\n"%(__command,__v) - __text += "%s_ScriptWithOneFunction['Script']['Tangent'] = %s\n"%(__command,__v) - __text += "%s_ScriptWithOneFunction['Script']['Adjoint'] = %s\n"%(__command,__v) - __text += "%s_ScriptWithOneFunction['DifferentialIncrement'] = 1e-06\n"%(__command,) - __text += "%s_ScriptWithOneFunction['CenteredFiniteDifference'] = 0\n"%(__command,) - __k = 'Function' - __f = 'ScriptWithOneFunction' - __v = '%s_ScriptWithOneFunction'%(__command,) - if 'ThreeFunctions' in __local and __local['ThreeFunctions']: - __text += "%s_ScriptWithFunctions = {}\n"%(__command,) - __text += "%s_ScriptWithFunctions['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,) - __text += "%s_ScriptWithFunctions['Script'] = {}\n"%(__command,) - __text += "%s_ScriptWithFunctions['Script']['Direct'] = %s\n"%(__command,__v) - __text += "%s_ScriptWithFunctions['Script']['Tangent'] = %s\n"%(__command,__v) - __text += "%s_ScriptWithFunctions['Script']['Adjoint'] = %s\n"%(__command,__v) - __k = 'Function' - __f = 'ScriptWithFunctions' - __v = '%s_ScriptWithFunctions'%(__command,) - __text += "%s_config['Type'] = '%s'\n"%(__command,__k) - __text += "%s_config['From'] = '%s'\n"%(__command,__f) - __text += "%s_config['Data'] = %s\n"%(__command,__v) - __text = __text.replace("''","'") - elif __k in ('Stored', 'Checked'): - if bool(__v): - __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v))) - elif __k in ('AvoidRC', 'noDetails'): - if not bool(__v): - __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v))) - else: - if __k is 'Parameters': __k = "Dict" - if isinstance(__v,Persistence.Persistence): __v = __v.values() - if callable(__v): __text = self._missing%__v.__name__+__text - if isinstance(__v,dict): - for val in __v.values(): - if callable(val): __text = self._missing%val.__name__+__text - __text += "%s_config['Type'] = '%s'\n"%(__command,__k) - __text += "%s_config['From'] = '%s'\n"%(__command,'String') - __text += "%s_config['Data'] = \"\"\"%s\"\"\"\n"%(__command,repr(__v)) - __text += "study_config['%s'] = %s_config"%(__command,__command) - numpy.set_printoptions(precision=8,threshold=1000,linewidth=75) - if __switchoff: - self._switchoff = True - if __text is not None: self._addLine(__text) - if not __switchoff: - self._switchoff = False - def _finalize(self): - self.__loadVariablesByScript() - self._addLine("#") - self._addLine("Analysis_config = {}") - self._addLine("Analysis_config['From'] = 'String'") - self._addLine("Analysis_config['Data'] = \"\"\"import numpy") - self._addLine("xa=numpy.ravel(ADD.get('Analysis')[-1])") - self._addLine("print 'Analysis:',xa\"\"\"") - self._addLine("study_config['UserPostAnalysis'] = Analysis_config") - def __loadVariablesByScript(self): - exec("\n".join(self._lineSerie)) - if "Algorithm" in study_config and len(study_config['Algorithm'])>0: - self.__hasAlgorithm = True - else: - self.__hasAlgorithm = False - if not self.__hasAlgorithm and \ - "AlgorithmParameters" in study_config and \ - isinstance(study_config['AlgorithmParameters'], dict) and \ - "From" in study_config['AlgorithmParameters'] and \ - "Data" in study_config['AlgorithmParameters'] and \ - study_config['AlgorithmParameters']['From'] == 'Script': - __asScript = study_config['AlgorithmParameters']['Data'] - __var = ImportFromScript(__asScript).getvalue( "Algorithm" ) - __text = "#\nstudy_config['Algorithm'] = '%s'"%(__var,) - self._addLine(__text) - if self.__hasAlgorithm and \ - "AlgorithmParameters" in study_config and \ - isinstance(study_config['AlgorithmParameters'], dict) and \ - "From" not in study_config['AlgorithmParameters'] and \ - "Data" not in study_config['AlgorithmParameters']: - __text = "#\n" - __text += "AlgorithmParameters_config['Type'] = 'Dict'\n" - __text += "AlgorithmParameters_config['From'] = 'String'\n" - __text += "AlgorithmParameters_config['Data'] = '{}'\n" - self._addLine(__text) - del study_config - -class XMLViewer(GenericCaseViewer): - """ - Etablissement des commandes de creation d'un cas XML - """ - def __init__(self, __name="", __objname="case", __content=None): - "Initialisation et enregistrement de l'entete" - GenericCaseViewer.__init__(self, __name, __objname, __content) - raise NotImplementedError() +# +from daCore import ExtendedLogging ; ExtendedLogging.ExtendedLogging() # A importer en premier +import logging # ============================================================================== class Aidsm(object): """ ADAO Internal Data Structure Model """ - def __init__(self, name = "", addViewers={"DIC":DICViewer}): - self.__name = str(name) + def __init__(self, name = "", addViewers=None): + self.__name = str(name) + self.__objname = None + self.__directory = None self.__case = CaseLogger(self.__name, "case", addViewers) # self.__adaoObject = {} self.__StoredInputs = {} + self.__PostAnalysis = [] # - self.__Concepts = [ + self.__Concepts = [ # Liste exhaustive "AlgorithmParameters", "Background", + "BackgroundError", "CheckingPoint", "ControlInput", - "Observation", - "Controls", - "BackgroundError", - "ObservationError", - "EvolutionError", - "ObservationOperator", - "EvolutionModel", "ControlModel", "Debug", + "Directory", + "EvolutionError", + "EvolutionModel", + "Name", "NoDebug", + "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 ("Diagnostic", "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, @@ -264,18 +99,20 @@ class Aidsm(object): Concept = None, # Premier argument Algorithm = None, AppliedInXb = None, - AvoidRC = True, - BaseType = None, Checked = False, - Diagnostic = None, + ColMajor = False, + ColNames = None, + DataFile = None, DiagonalSparseMatrix = None, - Identifier = None, + ExtraArguments = None, Info = None, + InputFunctionAsMulti = False, Matrix = None, ObjectFunction = None, ObjectMatrix = None, OneFunction = None, Parameters = None, + PerformanceProfile = None, ScalarSparseMatrix = None, Scheduler = None, Script = None, @@ -283,7 +120,6 @@ class Aidsm(object): String = None, Template = None, ThreeFunctions = None, - Unit = None, Variable = None, Vector = None, VectorSerie = None, @@ -291,39 +127,51 @@ class Aidsm(object): "Interface unique de definition de variables d'entrees par argument" self.__case.register("set",dir(),locals(),None,True) try: - if Concept in ("Background", "CheckingPoint", "ControlInput", "Observation", "Controls"): + if Concept in ("Background", "CheckingPoint", "ControlInput", "Observation"): commande = getattr(self,"set"+Concept) - commande(Vector, VectorSerie, Script, Scheduler, Stored, Checked ) + commande(Vector, VectorSerie, Script, DataFile, ColNames, ColMajor, Stored, Scheduler, Checked ) elif Concept in ("BackgroundError", "ObservationError", "EvolutionError"): commande = getattr(self,"set"+Concept) commande(Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, - ObjectMatrix, Script, Stored, Checked ) + Script, Stored, ObjectMatrix, Checked ) elif Concept == "AlgorithmParameters": self.setAlgorithmParameters( Algorithm, Parameters, Script ) + elif Concept == "RegulationParameters": + self.setRegulationParameters( Algorithm, Parameters, Script ) + elif Concept == "Name": + self.setName(String) + elif Concept == "Directory": + self.setDirectory(String) elif Concept == "Debug": self.setDebug() elif Concept == "NoDebug": self.setNoDebug() elif Concept == "Observer": - self.setObserver( Variable, Template, String, Script, ObjectFunction, Scheduler, Info ) - elif Concept == "Diagnostic": - self.setDiagnostic( Diagnostic, Identifier, Parameters, Script, Unit, BaseType ) + 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, AvoidRC, Stored, Checked ) + Parameters, Script, ExtraArguments, + Stored, PerformanceProfile, InputFunctionAsMulti, Checked ) elif Concept in ("EvolutionModel", "ControlModel"): commande = getattr(self,"set"+Concept) commande( Matrix, OneFunction, ThreeFunctions, - Parameters, Script, Scheduler, AvoidRC, Stored, Checked ) - + Parameters, Script, Scheduler, ExtraArguments, + 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, which can show the origin of the above error, in the launching terminal."%(str(e),msg)) + raise ValueError(("during settings, the following error occurs:\n"+\ + "\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)) # ----------------------------------------------------------- @@ -331,8 +179,11 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, + DataFile = None, + ColNames = None, + ColMajor = False, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "Background" @@ -341,7 +192,10 @@ class Aidsm(object): name = Concept, asVector = Vector, asPersistentVector = VectorSerie, - asScript = Script, + asScript = self.__with_directory(Script), + asDataFile = DataFile, + colNames = ColNames, + colMajor = ColMajor, scheduledBy = Scheduler, toBeChecked = Checked, ) @@ -353,8 +207,11 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, + DataFile = None, + ColNames = None, + ColMajor = False, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "CheckingPoint" @@ -363,7 +220,10 @@ class Aidsm(object): name = Concept, asVector = Vector, asPersistentVector = VectorSerie, - asScript = Script, + asScript = self.__with_directory(Script), + asDataFile = DataFile, + colNames = ColNames, + colMajor = ColMajor, scheduledBy = Scheduler, toBeChecked = Checked, ) @@ -375,8 +235,11 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, + DataFile = None, + ColNames = None, + ColMajor = False, Stored = False, + Scheduler = None, Checked = False): "Definition d'un concept de calcul" Concept = "ControlInput" @@ -385,7 +248,10 @@ class Aidsm(object): name = Concept, asVector = Vector, asPersistentVector = VectorSerie, - asScript = Script, + asScript = self.__with_directory(Script), + asDataFile = DataFile, + colNames = ColNames, + colMajor = ColMajor, scheduledBy = Scheduler, toBeChecked = Checked, ) @@ -397,39 +263,23 @@ class Aidsm(object): Vector = None, VectorSerie = None, Script = None, - Scheduler = None, + DataFile = None, + ColNames = None, + ColMajor = False, Stored = False, - Checked = False): - "Definition d'un concept de calcul" - Concept = "Observation" - self.__case.register("set"+Concept, dir(), locals()) - self.__adaoObject[Concept] = State( - name = Concept, - asVector = Vector, - asPersistentVector = VectorSerie, - asScript = Script, - scheduledBy = Scheduler, - toBeChecked = Checked, - ) - if Stored: - self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO() - return 0 - - def setControls(self, - Vector = (), # Valeur par defaut pour un vecteur vide - VectorSerie = None, - Script = None, Scheduler = None, - Stored = False, Checked = False): "Definition d'un concept de calcul" - Concept = "Controls" + Concept = "Observation" self.__case.register("set"+Concept, dir(), locals()) self.__adaoObject[Concept] = State( name = Concept, asVector = Vector, asPersistentVector = VectorSerie, - asScript = Script, + asScript = self.__with_directory(Script), + asDataFile = DataFile, + colNames = ColNames, + colMajor = ColMajor, scheduledBy = Scheduler, toBeChecked = Checked, ) @@ -441,9 +291,9 @@ class Aidsm(object): Matrix = None, ScalarSparseMatrix = None, DiagonalSparseMatrix = None, - ObjectMatrix = None, Script = None, Stored = False, + ObjectMatrix = None, Checked = False): "Definition d'un concept de calcul" Concept = "BackgroundError" @@ -454,7 +304,7 @@ class Aidsm(object): asEyeByScalar = ScalarSparseMatrix, asEyeByVector = DiagonalSparseMatrix, asCovObject = ObjectMatrix, - asScript = Script, + asScript = self.__with_directory(Script), toBeChecked = Checked, ) if Stored: @@ -465,9 +315,9 @@ class Aidsm(object): Matrix = None, ScalarSparseMatrix = None, DiagonalSparseMatrix = None, - ObjectMatrix = None, Script = None, Stored = False, + ObjectMatrix = None, Checked = False): "Definition d'un concept de calcul" Concept = "ObservationError" @@ -478,7 +328,7 @@ class Aidsm(object): asEyeByScalar = ScalarSparseMatrix, asEyeByVector = DiagonalSparseMatrix, asCovObject = ObjectMatrix, - asScript = Script, + asScript = self.__with_directory(Script), toBeChecked = Checked, ) if Stored: @@ -489,9 +339,9 @@ class Aidsm(object): Matrix = None, ScalarSparseMatrix = None, DiagonalSparseMatrix = None, - ObjectMatrix = None, Script = None, Stored = False, + ObjectMatrix = None, Checked = False): "Definition d'un concept de calcul" Concept = "EvolutionError" @@ -502,7 +352,7 @@ class Aidsm(object): asEyeByScalar = ScalarSparseMatrix, asEyeByVector = DiagonalSparseMatrix, asCovObject = ObjectMatrix, - asScript = Script, + asScript = self.__with_directory(Script), toBeChecked = Checked, ) if Stored: @@ -510,15 +360,17 @@ class Aidsm(object): return 0 def setObservationOperator(self, - Matrix = None, - OneFunction = None, - ThreeFunctions = None, - AppliedInXb = None, - Parameters = None, - Script = None, - AvoidRC = True, - Stored = False, - Checked = False): + Matrix = None, + OneFunction = None, + ThreeFunctions = None, + AppliedInXb = None, + Parameters = None, + Script = None, + ExtraArguments = None, + Stored = False, + PerformanceProfile = None, + InputFunctionAsMulti = False, + Checked = False): "Definition d'un concept de calcul" Concept = "ObservationOperator" self.__case.register("set"+Concept, dir(), locals()) @@ -527,10 +379,12 @@ class Aidsm(object): asMatrix = Matrix, asOneFunction = OneFunction, asThreeFunctions = ThreeFunctions, - asScript = Script, + asScript = self.__with_directory(Script), asDict = Parameters, appliedInX = AppliedInXb, - avoidRC = AvoidRC, + extraArguments = ExtraArguments, + performancePrf = PerformanceProfile, + inputAsMF = InputFunctionAsMulti, scheduledBy = None, toBeChecked = Checked, ) @@ -539,15 +393,17 @@ class Aidsm(object): return 0 def setEvolutionModel(self, - Matrix = None, - OneFunction = None, - ThreeFunctions = None, - Parameters = None, - Script = None, - Scheduler = None, - AvoidRC = True, - Stored = False, - Checked = False): + Matrix = None, + OneFunction = None, + ThreeFunctions = None, + Parameters = None, + Script = None, + Scheduler = None, + ExtraArguments = None, + Stored = False, + PerformanceProfile = None, + InputFunctionAsMulti = False, + Checked = False): "Definition d'un concept de calcul" Concept = "EvolutionModel" self.__case.register("set"+Concept, dir(), locals()) @@ -556,10 +412,12 @@ class Aidsm(object): asMatrix = Matrix, asOneFunction = OneFunction, asThreeFunctions = ThreeFunctions, - asScript = Script, + asScript = self.__with_directory(Script), asDict = Parameters, appliedInX = None, - avoidRC = AvoidRC, + extraArguments = ExtraArguments, + performancePrf = PerformanceProfile, + inputAsMF = InputFunctionAsMulti, scheduledBy = Scheduler, toBeChecked = Checked, ) @@ -568,15 +426,17 @@ class Aidsm(object): return 0 def setControlModel(self, - Matrix = None, - OneFunction = None, - ThreeFunctions = None, - Parameters = None, - Script = None, - Scheduler = None, - AvoidRC = True, - Stored = False, - Checked = False): + Matrix = None, + OneFunction = None, + ThreeFunctions = None, + Parameters = None, + Script = None, + Scheduler = None, + ExtraArguments = None, + Stored = False, + PerformanceProfile = None, + InputFunctionAsMulti = False, + Checked = False): "Definition d'un concept de calcul" Concept = "ControlModel" self.__case.register("set"+Concept, dir(), locals()) @@ -585,10 +445,12 @@ class Aidsm(object): asMatrix = Matrix, asOneFunction = OneFunction, asThreeFunctions = ThreeFunctions, - asScript = Script, + asScript = self.__with_directory(Script), asDict = Parameters, appliedInX = None, - avoidRC = AvoidRC, + extraArguments = ExtraArguments, + performancePrf = PerformanceProfile, + inputAsMF = InputFunctionAsMulti, scheduledBy = Scheduler, toBeChecked = Checked, ) @@ -596,12 +458,30 @@ class Aidsm(object): self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO() return 0 - def setDebug(self, level = 10): + def setName(self, String=None): + "Definition d'un concept de calcul" + self.__case.register("setName",dir(),locals()) + if String is not None: + self.__name = str(String) + else: + self.__name = None + self.__StoredInputs["Name"] = self.__name + + def setDirectory(self, String=None): + "Definition 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)) + else: + self.__directory = None + self.__StoredInputs["Directory"] = self.__directory + + def setDebug(self, __level = 10): "NOTSET=0 < DEBUG=10 < INFO=20 < WARNING=30 < ERROR=40 < CRITICAL=50" self.__case.register("setDebug",dir(),locals()) log = logging.getLogger() - log.setLevel( level ) - self.__StoredInputs["Debug"] = level + log.setLevel( __level ) + self.__StoredInputs["Debug"] = __level self.__StoredInputs["NoDebug"] = False return 0 @@ -625,7 +505,7 @@ class Aidsm(object): name = Concept, asAlgorithm = Algorithm, asDict = Parameters, - asScript = Script, + asScript = self.__with_directory(Script), ) return 0 @@ -633,11 +513,54 @@ class Aidsm(object): 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( + 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 = Script, + 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" + Concept = "RegulationParameters" + self.__case.register("set"+Concept, dir(), locals()) + self.__adaoObject[Concept] = RegulationAndParameters( + name = Concept, + asAlgorithm = Algorithm, + asDict = Parameters, + asScript = self.__with_directory(Script), + ) + return 0 + + def setSupplementaryParameters(self, + Parameters = None, + Script = None): + "Definition 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 a 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 @@ -646,9 +569,9 @@ class Aidsm(object): Template = None, String = None, Script = None, + Info = None, ObjectFunction = None, - Scheduler = None, - Info = None): + Scheduler = None): "Definition d'un concept de calcul" Concept = "Observer" self.__case.register("set"+Concept, dir(), locals()) @@ -657,7 +580,7 @@ class Aidsm(object): onVariable = Variable, asTemplate = Template, asString = String, - asScript = Script, + asScript = self.__with_directory(Script), asObsObject = ObjectFunction, withInfo = Info, scheduledBy = Scheduler, @@ -669,9 +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ée" if "AlgorithmParameters" not in self.__adaoObject: raise ValueError("No algorithm registred, ask for one before removing observers") # @@ -692,44 +613,29 @@ class Aidsm(object): else: return self.__adaoObject["AlgorithmParameters"].removeObserver( ename, ObjectFunction ) - # ----------------------------------------------------------- - - def setDiagnostic(self, - Diagnostic = None, - Identifier = None, - Parameters = None, - Script = None, - Unit = None, - BaseType = None): + def setUserPostAnalysis(self, + Template = None, + String = None, + Script = None): "Definition d'un concept de calcul" - Concept = "Diagnostic" + Concept = "UserPostAnalysis" self.__case.register("set"+Concept, dir(), locals()) - self.__adaoObject[Concept].append( DiagnosticAndParameters( - name = Concept, - asDiagnostic = Diagnostic, - asIdentifier = Identifier, - asDict = Parameters, - asScript = Script, - asUnit = Unit, - asBaseType = BaseType, - asExistingDiags = self.__StoredInputs[Concept], - )) - self.__StoredInputs[Concept].append(str(Identifier)) + 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" - """ - Permet d'accéder aux informations stockées, diagnostics et résultats - disponibles après l'exécution du calcul. Attention, quand un diagnostic - porte le même nom qu'une variable stockée (paramètre ou résultat), - c'est la variable stockée qui est renvoyée, et le diagnostic est - inatteignable. - """ if Concept is not None: try: self.__case.register("get", dir(), locals(), Concept) # Break pickle in Python 2 - except: + except Exception: pass if Concept in self.__StoredInputs: return self.__StoredInputs[Concept] @@ -743,19 +649,29 @@ class Aidsm(object): elif Concept == "AlgorithmRequiredParameters" and self.__adaoObject["AlgorithmParameters"] is not None: return self.__adaoObject["AlgorithmParameters"].getAlgorithmRequiredParameters(noDetails) # - elif Concept in self.__StoredInputs["Diagnostic"]: - indice = self.__StoredInputs["Diagnostic"].index(Concept) - return self.__adaoObject["Diagnostic"][indice].get() + 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, a diagnostic or a stored variable."%Concept) + 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()} ) - allvariables.update( 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('Diagnostic', None) allvariables.pop('Observer', None) + allvariables.pop('UserPostAnalysis', None) return allvariables # ----------------------------------------------------------- @@ -774,10 +690,13 @@ 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('Diagnostic') variables.remove('Observer') + variables.remove('UserPostAnalysis') variables.sort() return variables @@ -788,35 +707,22 @@ class Aidsm(object): """ files = [] for directory in sys.path: - if os.path.isdir(os.path.join(directory,"daAlgorithms")): - for fname in os.listdir(os.path.join(directory,"daAlgorithms")): - root, ext = os.path.splitext(fname) - if ext == '.py' and root != '__init__': - files.append(root) - files.sort() - return files - - def get_available_diagnostics(self): - """ - Renvoie la liste des diagnostics potentiellement utilisables, identifiés - par les chaînes de caractères. - """ - files = [] - for directory in sys.path: - if os.path.isdir(os.path.join(directory,"daDiagnostics")): - for fname in os.listdir(os.path.join(directory,"daDiagnostics")): - root, ext = os.path.splitext(fname) - if ext == '.py' and root != '__init__': - files.append(root) + trypath = os.path.join(directory,"daAlgorithms") + if os.path.isdir(trypath): + for fname in os.listdir(trypath): + if os.path.isfile(os.path.join(trypath,fname)): + root, ext = os.path.splitext(fname) + if ext != ".py": continue + 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): """ Renvoie le chemin pour le répertoire principal contenant les algorithmes - dans un sous-répertoire "daAlgorithms" """ return self.__parent @@ -824,9 +730,6 @@ class Aidsm(object): """ Ajoute au chemin de recherche des algorithmes un répertoire dans lequel se trouve un sous-répertoire "daAlgorithms" - - Remarque : si le chemin a déjà été ajouté pour les diagnostics, il n'est - pas indispensable de le rajouter ici. """ if not os.path.isdir(Path): raise ValueError("The given "+Path+" argument must exist as a directory") @@ -838,44 +741,23 @@ class Aidsm(object): sys.path = PlatformInfo.uniq( sys.path ) # Conserve en unique exemplaire chaque chemin return 0 - def get_diagnostics_main_path(self): - """ - Renvoie le chemin pour le répertoire principal contenant les diagnostics - dans un sous-répertoire "daDiagnostics" - """ - return self.__parent - - def add_diagnostics_path(self, Path=None): - """ - Ajoute au chemin de recherche des algorithmes un répertoire dans lequel - se trouve un sous-répertoire "daDiagnostics" - - Remarque : si le chemin a déjà été ajouté pour les algorithmes, il n'est - pas indispensable de le rajouter ici. - """ - if not os.path.isdir(Path): - raise ValueError("The given "+Path+" argument must exist as a directory") - if not os.path.isdir(os.path.join(Path,"daDiagnostics")): - raise ValueError("The given \""+Path+"\" argument must contain a subdirectory named \"daDiagnostics\"") - if not os.path.isfile(os.path.join(Path,"daDiagnostics","__init__.py")): - raise ValueError("The given \""+Path+"/daDiagnostics\" path must contain a file named \"__init__.py\"") - sys.path.insert(0, os.path.abspath(Path)) - sys.path = PlatformInfo.uniq( sys.path ) # Conserve en unique exemplaire chaque chemin - return 0 - # ----------------------------------------------------------- - 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 ) except Exception as e: if isinstance(e, SyntaxError): msg = "at %s: %s"%(e.offset, e.text) else: msg = "" - raise ValueError("during execution, the following error occurs:\n\n%s %s\n\nSee also the potential messages, which can show the origin of the above error, in the launching terminal.\n"%(str(e),msg)) + raise ValueError(("during execution, the following error occurs:\n"+\ + "\n%s %s\n\nSee also the potential messages, "+\ + "which can show the origin of the above error, "+\ + "in the launching terminal.\n")%(str(e),msg)) return 0 def __executePythonScheme(self, FileName=None): @@ -884,13 +766,17 @@ 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): "Lancement du calcul" self.__case.register("executeYACSScheme", dir(), locals()) - if FileName is not None: - self.dump( FileName, "DIC") + self.dump( FileName, "YACS") self.__adaoObject["AlgorithmParameters"].executeYACSScheme( FileName ) return 0 @@ -898,15 +784,30 @@ class Aidsm(object): def dump(self, FileName=None, Formater="TUI"): "Restitution normalisée des commandes" - return self.__case.dump(FileName, Formater) + __Upa = "\n".join(self.__PostAnalysis) + return self.__case.dump(FileName, Formater, __Upa) - def load(self, FileName=None, Formater="TUI"): + def load(self, FileName=None, Content=None, Object=None, Formater="TUI"): "Chargement normalisé des commandes" - __commands = self.__case.load(FileName, Formater) + __commands = self.__case.load(FileName, Content, Object, Formater) from numpy import array, matrix for __command in __commands: - exec("self."+__command) - return 0 + 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 + + def convert(self, + FileNameFrom=None, ContentFrom=None, ObjectFrom=None, FormaterFrom="TUI", + FileNameTo=None, FormaterTo="TUI", + ): + "Conversion normalisée des commandes" + return self.load( + FileName=FileNameFrom, Content=ContentFrom, Object=ObjectFrom, Formater=FormaterFrom + ).dump( + FileName=FileNameTo, Formater=FormaterTo + ) def clear(self): "Effacement du contenu du cas en cours" @@ -914,9 +815,36 @@ class Aidsm(object): # ----------------------------------------------------------- + def __with_directory(self, __filename=None): + if os.path.exists(str(__filename)): + __fullpath = __filename + elif os.path.exists(os.path.join(str(self.__directory), str(__filename))): + __fullpath = os.path.join(self.__directory, str(__filename)) + else: + __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', '__doc__', '__init__', '__module__'] + 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" @@ -924,14 +852,18 @@ class Aidsm(object): 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) - del self.__adaoObject # Because it breaks pickle in Python 2. Not required for Python 3 - del self.__case # Because it breaks pickle in Python 2. Not required for Python 3 - return 0 + if sys.version_info[0] == 2: + del self.__adaoObject # Because it breaks pickle in Python 2. Not required for Python 3 + del self.__case # Because it breaks pickle in Python 2. Not required for Python 3 + if sys.version_info.major < 3: + return 0 + else: + return self.__StoredInputs # ============================================================================== if __name__ == "__main__": - print('\n AUTODIAGNOSTIC \n') + print('\n AUTODIAGNOSTIC\n')