Salome HOME
Documentation and SALOME support corrections
[modules/adao.git] / src / daComposant / daCore / Aidsm.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2017 EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
22
23 """
24     Normalized interface for ADAO scripting (generic API)
25 """
26 __author__ = "Jean-Philippe ARGAUD"
27 __all__ = ["Aidsm"]
28
29 import os, sys
30 from daCore import ExtendedLogging ; ExtendedLogging.ExtendedLogging() # A importer en premier
31 import logging
32 import numpy
33 #
34 from daCore.BasicObjects import State, Covariance, FullOperator, Operator
35 from daCore.BasicObjects import AlgorithmAndParameters, DataObserver
36 from daCore.BasicObjects import DiagnosticAndParameters, ImportFromScript
37 from daCore.BasicObjects import CaseLogger, GenericCaseViewer
38 from daCore.Templates    import ObserverTemplates
39 from daCore import Persistence
40 from daCore import PlatformInfo
41
42 # ==============================================================================
43 class DICViewer(GenericCaseViewer):
44     """
45     Etablissement des commandes de creation d'un cas DIC
46     """
47     def __init__(self, __name="", __objname="case", __content=None):
48         "Initialisation et enregistrement de l'entete"
49         GenericCaseViewer.__init__(self, __name, __objname, __content)
50         self._addLine("# -*- coding: utf-8 -*-")
51         self._addLine("#\n# Input for ADAO converter to YACS\n#")
52         self._addLine("from numpy import array, matrix")
53         self._addLine("#")
54         self._addLine("study_config = {}")
55         self._addLine("study_config['StudyType'] = 'ASSIMILATION_STUDY'")
56         self._addLine("study_config['Name'] = '%s'"%self._name)
57         self._addLine("observers = {}")
58         self._addLine("study_config['Observers'] = observers")
59         self._addLine("#")
60         self._addLine("inputvariables_config = {}")
61         self._addLine("inputvariables_config['Order'] =['adao_default']")
62         self._addLine("inputvariables_config['adao_default'] = -1")
63         self._addLine("study_config['InputVariables'] = inputvariables_config")
64         self._addLine("#")
65         self._addLine("outputvariables_config = {}")
66         self._addLine("outputvariables_config['Order'] = ['adao_default']")
67         self._addLine("outputvariables_config['adao_default'] = -1")
68         self._addLine("study_config['OutputVariables'] = outputvariables_config")
69         if __content is not None:
70             for command in __content:
71                 self._append(*command)
72     def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
73         "Transformation d'une commande individuelle en un enregistrement"
74         if __command == "set": __command = __local["Concept"]
75         else:                  __command = __command.replace("set", "", 1)
76         #
77         __text  = None
78         if __command in (None, 'execute', 'executePythonScheme', 'executeYACSScheme', 'get'):
79             return
80         elif __command in ['Debug', 'setDebug']:
81             __text  = "#\nstudy_config['Debug'] = '1'"
82         elif __command in ['NoDebug', 'setNoDebug']:
83             __text  = "#\nstudy_config['Debug'] = '0'"
84         elif __command in ['Observer', 'setObserver']:
85             __obs   = __local['Variable']
86             self._numobservers += 1
87             __text  = "#\n"
88             __text += "observers['%s'] = {}\n"%__obs
89             if __local['String'] is not None:
90                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
91                 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, __local['String'])
92             if __local['Script'] is not None:
93                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'Script')
94                 __text += "observers['%s']['Script'] = \"%s\"\n"%(__obs, __local['Script'])
95             if __local['Template'] is not None:
96                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
97                 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, ObserverTemplates[__local['Template']])
98             if __local['Info'] is not None:
99                 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __local['Info'])
100             else:
101                 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __obs)
102             __text += "observers['%s']['number'] = %s"%(__obs, self._numobservers)
103         elif __local is not None: # __keys is not None and
104             numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
105             __text  = "#\n"
106             __text += "%s_config = {}\n"%__command
107             if 'self' in __local: __local.pop('self')
108             __to_be_removed = []
109             for __k,__v in __local.items():
110                 if __v is None: __to_be_removed.append(__k)
111             for __k in __to_be_removed:
112                     __local.pop(__k)
113             for __k,__v in __local.items():
114                 if __k == "Concept": continue
115                 if __k in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix','OneFunction','ThreeFunctions'] and 'Script' in __local: continue
116                 if __k == 'Algorithm':
117                     __text += "study_config['Algorithm'] = %s\n"%(repr(__v))
118                 elif __k == 'Script':
119                     __k = 'Vector'
120                     __f = 'Script'
121                     __v = "'"+repr(__v)+"'"
122                     for __lk in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix']:
123                         if __lk in __local and __local[__lk]: __k = __lk
124                     if __command == "AlgorithmParameters": __k = "Dict"
125                     if 'OneFunction' in __local and __local['OneFunction']:
126                         __text += "%s_ScriptWithOneFunction = {}\n"%(__command,)
127                         __text += "%s_ScriptWithOneFunction['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
128                         __text += "%s_ScriptWithOneFunction['Script'] = {}\n"%(__command,)
129                         __text += "%s_ScriptWithOneFunction['Script']['Direct'] = %s\n"%(__command,__v)
130                         __text += "%s_ScriptWithOneFunction['Script']['Tangent'] = %s\n"%(__command,__v)
131                         __text += "%s_ScriptWithOneFunction['Script']['Adjoint'] = %s\n"%(__command,__v)
132                         __text += "%s_ScriptWithOneFunction['DifferentialIncrement'] = 1e-06\n"%(__command,)
133                         __text += "%s_ScriptWithOneFunction['CenteredFiniteDifference'] = 0\n"%(__command,)
134                         __k = 'Function'
135                         __f = 'ScriptWithOneFunction'
136                         __v = '%s_ScriptWithOneFunction'%(__command,)
137                     if 'ThreeFunctions' in __local and __local['ThreeFunctions']:
138                         __text += "%s_ScriptWithFunctions = {}\n"%(__command,)
139                         __text += "%s_ScriptWithFunctions['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
140                         __text += "%s_ScriptWithFunctions['Script'] = {}\n"%(__command,)
141                         __text += "%s_ScriptWithFunctions['Script']['Direct'] = %s\n"%(__command,__v)
142                         __text += "%s_ScriptWithFunctions['Script']['Tangent'] = %s\n"%(__command,__v)
143                         __text += "%s_ScriptWithFunctions['Script']['Adjoint'] = %s\n"%(__command,__v)
144                         __k = 'Function'
145                         __f = 'ScriptWithFunctions'
146                         __v = '%s_ScriptWithFunctions'%(__command,)
147                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
148                     __text += "%s_config['From'] = '%s'\n"%(__command,__f)
149                     __text += "%s_config['Data'] = %s\n"%(__command,__v)
150                     __text = __text.replace("''","'")
151                 elif __k in ('Stored', 'Checked'):
152                     if bool(__v):
153                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
154                 elif __k in ('AvoidRC', 'noDetails'):
155                     if not bool(__v):
156                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
157                 else:
158                     if __k is 'Parameters': __k = "Dict"
159                     if isinstance(__v,Persistence.Persistence): __v = __v.values()
160                     if callable(__v): __text = self._missing%__v.__name__+__text
161                     if isinstance(__v,dict):
162                         for val in __v.values():
163                             if callable(val): __text = self._missing%val.__name__+__text
164                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
165                     __text += "%s_config['From'] = '%s'\n"%(__command,'String')
166                     __text += "%s_config['Data'] = \"\"\"%s\"\"\"\n"%(__command,repr(__v))
167             __text += "study_config['%s'] = %s_config"%(__command,__command)
168             numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
169             if __switchoff:
170                 self._switchoff = True
171         if __text is not None: self._addLine(__text)
172         if not __switchoff:
173             self._switchoff = False
174     def _finalize(self):
175         self.__loadVariablesByScript()
176         self._addLine("#")
177         self._addLine("Analysis_config = {}")
178         self._addLine("Analysis_config['From'] = 'String'")
179         self._addLine("Analysis_config['Data'] = \"\"\"import numpy")
180         self._addLine("xa=numpy.ravel(ADD.get('Analysis')[-1])")
181         self._addLine("print 'Analysis:',xa\"\"\"")
182         self._addLine("study_config['UserPostAnalysis'] = Analysis_config")
183     def __loadVariablesByScript(self):
184         exec("\n".join(self._lineSerie))
185         if "Algorithm" in study_config and len(study_config['Algorithm'])>0:
186             self.__hasAlgorithm = True
187         else:
188             self.__hasAlgorithm = False
189         if not self.__hasAlgorithm and \
190                 "AlgorithmParameters" in study_config and \
191                 isinstance(study_config['AlgorithmParameters'], dict) and \
192                 "From" in study_config['AlgorithmParameters'] and \
193                 "Data" in study_config['AlgorithmParameters'] and \
194                 study_config['AlgorithmParameters']['From'] == 'Script':
195             __asScript = study_config['AlgorithmParameters']['Data']
196             __var = ImportFromScript(__asScript).getvalue( "Algorithm" )
197             __text = "#\nstudy_config['Algorithm'] = '%s'"%(__var,)
198             self._addLine(__text)
199         if self.__hasAlgorithm and \
200                 "AlgorithmParameters" in study_config and \
201                 isinstance(study_config['AlgorithmParameters'], dict) and \
202                 "From" not in study_config['AlgorithmParameters'] and \
203                 "Data" not in study_config['AlgorithmParameters']:
204             __text  = "#\n"
205             __text += "AlgorithmParameters_config['Type'] = 'Dict'\n"
206             __text += "AlgorithmParameters_config['From'] = 'String'\n"
207             __text += "AlgorithmParameters_config['Data'] = '{}'\n"
208             self._addLine(__text)
209         del study_config
210
211 class XMLViewer(GenericCaseViewer):
212     """
213     Etablissement des commandes de creation d'un cas XML
214     """
215     def __init__(self, __name="", __objname="case", __content=None):
216         "Initialisation et enregistrement de l'entete"
217         GenericCaseViewer.__init__(self, __name, __objname, __content)
218         raise NotImplementedError()
219
220 # ==============================================================================
221 class Aidsm(object):
222     """ ADAO Internal Data Structure Model """
223     def __init__(self, name = "", addViewers={"DIC":DICViewer}):
224         self.__name = str(name)
225         self.__case = CaseLogger(self.__name, "case", addViewers)
226         #
227         self.__adaoObject   = {}
228         self.__StoredInputs = {}
229         #
230         self.__Concepts = [
231             "AlgorithmParameters",
232             "Background",
233             "CheckingPoint",
234             "ControlInput",
235             "Observation",
236             "Controls",
237             "BackgroundError",
238             "ObservationError",
239             "EvolutionError",
240             "ObservationOperator",
241             "EvolutionModel",
242             "ControlModel",
243             "Debug",
244             "NoDebug",
245             "Observer",
246             ]
247         #
248         for ename in self.__Concepts:
249             self.__adaoObject[ename] = None
250         for ename in ("ObservationOperator", "EvolutionModel", "ControlModel"):
251             self.__adaoObject[ename] = {}
252         for ename in ("Diagnostic", "Observer"):
253             self.__adaoObject[ename]   = []
254             self.__StoredInputs[ename] = []
255         #
256         # Récupère le chemin du répertoire parent et l'ajoute au path
257         # (Cela complète l'action de la classe PathManagement dans PlatformInfo,
258         # qui est activée dans Persistence)
259         self.__parent = os.path.abspath(os.path.join(os.path.dirname(__file__),".."))
260         sys.path.insert(0, self.__parent)
261         sys.path = PlatformInfo.uniq( sys.path ) # Conserve en unique exemplaire chaque chemin
262
263     def set(self,
264             Concept              = None, # Premier argument
265             Algorithm            = None,
266             AppliedInXb          = None,
267             AvoidRC              = True,
268             BaseType             = None,
269             Checked              = False,
270             Diagnostic           = None,
271             DiagonalSparseMatrix = None,
272             Identifier           = None,
273             Info                 = None,
274             Matrix               = None,
275             ObjectFunction       = None,
276             ObjectMatrix         = None,
277             OneFunction          = None,
278             Parameters           = None,
279             ScalarSparseMatrix   = None,
280             Scheduler            = None,
281             Script               = None,
282             Stored               = False,
283             String               = None,
284             Template             = None,
285             ThreeFunctions       = None,
286             Unit                 = None,
287             Variable             = None,
288             Vector               = None,
289             VectorSerie          = None,
290             ):
291         "Interface unique de definition de variables d'entrees par argument"
292         self.__case.register("set",dir(),locals(),None,True)
293         try:
294             if   Concept in ("Background", "CheckingPoint", "ControlInput", "Observation", "Controls"):
295                 commande = getattr(self,"set"+Concept)
296                 commande(Vector, VectorSerie, Script, Scheduler, Stored, Checked )
297             elif Concept in ("BackgroundError", "ObservationError", "EvolutionError"):
298                 commande = getattr(self,"set"+Concept)
299                 commande(Matrix, ScalarSparseMatrix, DiagonalSparseMatrix,
300                          ObjectMatrix, Script, Stored, Checked )
301             elif Concept == "AlgorithmParameters":
302                 self.setAlgorithmParameters( Algorithm, Parameters, Script )
303             elif Concept == "Debug":
304                 self.setDebug()
305             elif Concept == "NoDebug":
306                 self.setNoDebug()
307             elif Concept == "Observer":
308                 self.setObserver( Variable, Template, String, Script, ObjectFunction, Scheduler, Info )
309             elif Concept == "Diagnostic":
310                 self.setDiagnostic( Diagnostic, Identifier, Parameters, Script, Unit, BaseType )
311             elif Concept == "ObservationOperator":
312                 self.setObservationOperator(
313                     Matrix, OneFunction, ThreeFunctions, AppliedInXb,
314                     Parameters, Script, AvoidRC, Stored, Checked )
315             elif Concept in ("EvolutionModel", "ControlModel"):
316                 commande = getattr(self,"set"+Concept)
317                 commande(
318                     Matrix, OneFunction, ThreeFunctions,
319                     Parameters, Script, Scheduler, AvoidRC, Stored, Checked )
320
321             else:
322                 raise ValueError("the variable named '%s' is not allowed."%str(Concept))
323         except Exception as e:
324             if isinstance(e, SyntaxError): msg = "at %s: %s"%(e.offset, e.text)
325             else: msg = ""
326             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))
327
328     # -----------------------------------------------------------
329
330     def setBackground(self,
331             Vector         = None,
332             VectorSerie    = None,
333             Script         = None,
334             Scheduler      = None,
335             Stored         = False,
336             Checked        = False):
337         "Definition d'un concept de calcul"
338         Concept = "Background"
339         self.__case.register("set"+Concept, dir(), locals())
340         self.__adaoObject[Concept] = State(
341             name               = Concept,
342             asVector           = Vector,
343             asPersistentVector = VectorSerie,
344             asScript           = Script,
345             scheduledBy        = Scheduler,
346             toBeChecked        = Checked,
347             )
348         if Stored:
349             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
350         return 0
351
352     def setCheckingPoint(self,
353             Vector         = None,
354             VectorSerie    = None,
355             Script         = None,
356             Scheduler      = None,
357             Stored         = False,
358             Checked        = False):
359         "Definition d'un concept de calcul"
360         Concept = "CheckingPoint"
361         self.__case.register("set"+Concept, dir(), locals())
362         self.__adaoObject[Concept] = State(
363             name               = Concept,
364             asVector           = Vector,
365             asPersistentVector = VectorSerie,
366             asScript           = Script,
367             scheduledBy        = Scheduler,
368             toBeChecked        = Checked,
369             )
370         if Stored:
371             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
372         return 0
373
374     def setControlInput(self,
375             Vector         = None,
376             VectorSerie    = None,
377             Script         = None,
378             Scheduler      = None,
379             Stored         = False,
380             Checked        = False):
381         "Definition d'un concept de calcul"
382         Concept = "ControlInput"
383         self.__case.register("set"+Concept, dir(), locals())
384         self.__adaoObject[Concept] = State(
385             name               = Concept,
386             asVector           = Vector,
387             asPersistentVector = VectorSerie,
388             asScript           = Script,
389             scheduledBy        = Scheduler,
390             toBeChecked        = Checked,
391             )
392         if Stored:
393             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
394         return 0
395
396     def setObservation(self,
397             Vector         = None,
398             VectorSerie    = None,
399             Script         = None,
400             Scheduler      = None,
401             Stored         = False,
402             Checked        = False):
403         "Definition d'un concept de calcul"
404         Concept = "Observation"
405         self.__case.register("set"+Concept, dir(), locals())
406         self.__adaoObject[Concept] = State(
407             name               = Concept,
408             asVector           = Vector,
409             asPersistentVector = VectorSerie,
410             asScript           = Script,
411             scheduledBy        = Scheduler,
412             toBeChecked        = Checked,
413             )
414         if Stored:
415             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
416         return 0
417
418     def setControls(self,
419             Vector         = (), # Valeur par defaut pour un vecteur vide
420             VectorSerie    = None,
421             Script         = None,
422             Scheduler      = None,
423             Stored         = False,
424             Checked        = False):
425         "Definition d'un concept de calcul"
426         Concept = "Controls"
427         self.__case.register("set"+Concept, dir(), locals())
428         self.__adaoObject[Concept] = State(
429             name               = Concept,
430             asVector           = Vector,
431             asPersistentVector = VectorSerie,
432             asScript           = Script,
433             scheduledBy        = Scheduler,
434             toBeChecked        = Checked,
435             )
436         if Stored:
437             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
438         return 0
439
440     def setBackgroundError(self,
441             Matrix               = None,
442             ScalarSparseMatrix   = None,
443             DiagonalSparseMatrix = None,
444             ObjectMatrix         = None,
445             Script               = None,
446             Stored               = False,
447             Checked              = False):
448         "Definition d'un concept de calcul"
449         Concept = "BackgroundError"
450         self.__case.register("set"+Concept, dir(), locals())
451         self.__adaoObject[Concept] = Covariance(
452             name          = Concept,
453             asCovariance  = Matrix,
454             asEyeByScalar = ScalarSparseMatrix,
455             asEyeByVector = DiagonalSparseMatrix,
456             asCovObject   = ObjectMatrix,
457             asScript      = Script,
458             toBeChecked   = Checked,
459             )
460         if Stored:
461             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
462         return 0
463
464     def setObservationError(self,
465             Matrix               = None,
466             ScalarSparseMatrix   = None,
467             DiagonalSparseMatrix = None,
468             ObjectMatrix         = None,
469             Script               = None,
470             Stored               = False,
471             Checked              = False):
472         "Definition d'un concept de calcul"
473         Concept = "ObservationError"
474         self.__case.register("set"+Concept, dir(), locals())
475         self.__adaoObject[Concept] = Covariance(
476             name          = Concept,
477             asCovariance  = Matrix,
478             asEyeByScalar = ScalarSparseMatrix,
479             asEyeByVector = DiagonalSparseMatrix,
480             asCovObject   = ObjectMatrix,
481             asScript      = Script,
482             toBeChecked   = Checked,
483             )
484         if Stored:
485             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
486         return 0
487
488     def setEvolutionError(self,
489             Matrix               = None,
490             ScalarSparseMatrix   = None,
491             DiagonalSparseMatrix = None,
492             ObjectMatrix         = None,
493             Script               = None,
494             Stored               = False,
495             Checked              = False):
496         "Definition d'un concept de calcul"
497         Concept = "EvolutionError"
498         self.__case.register("set"+Concept, dir(), locals())
499         self.__adaoObject[Concept] = Covariance(
500             name          = Concept,
501             asCovariance  = Matrix,
502             asEyeByScalar = ScalarSparseMatrix,
503             asEyeByVector = DiagonalSparseMatrix,
504             asCovObject   = ObjectMatrix,
505             asScript      = Script,
506             toBeChecked   = Checked,
507             )
508         if Stored:
509             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
510         return 0
511
512     def setObservationOperator(self,
513             Matrix         = None,
514             OneFunction    = None,
515             ThreeFunctions = None,
516             AppliedInXb    = None,
517             Parameters     = None,
518             Script         = None,
519             AvoidRC        = True,
520             Stored         = False,
521             Checked        = False):
522         "Definition d'un concept de calcul"
523         Concept = "ObservationOperator"
524         self.__case.register("set"+Concept, dir(), locals())
525         self.__adaoObject[Concept] = FullOperator(
526             name             = Concept,
527             asMatrix         = Matrix,
528             asOneFunction    = OneFunction,
529             asThreeFunctions = ThreeFunctions,
530             asScript         = Script,
531             asDict           = Parameters,
532             appliedInX       = AppliedInXb,
533             avoidRC          = AvoidRC,
534             scheduledBy      = None,
535             toBeChecked      = Checked,
536             )
537         if Stored:
538             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
539         return 0
540
541     def setEvolutionModel(self,
542             Matrix         = None,
543             OneFunction    = None,
544             ThreeFunctions = None,
545             Parameters     = None,
546             Script         = None,
547             Scheduler      = None,
548             AvoidRC        = True,
549             Stored         = False,
550             Checked        = False):
551         "Definition d'un concept de calcul"
552         Concept = "EvolutionModel"
553         self.__case.register("set"+Concept, dir(), locals())
554         self.__adaoObject[Concept] = FullOperator(
555             name             = Concept,
556             asMatrix         = Matrix,
557             asOneFunction    = OneFunction,
558             asThreeFunctions = ThreeFunctions,
559             asScript         = Script,
560             asDict           = Parameters,
561             appliedInX       = None,
562             avoidRC          = AvoidRC,
563             scheduledBy      = Scheduler,
564             toBeChecked      = Checked,
565             )
566         if Stored:
567             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
568         return 0
569
570     def setControlModel(self,
571             Matrix         = None,
572             OneFunction    = None,
573             ThreeFunctions = None,
574             Parameters     = None,
575             Script         = None,
576             Scheduler      = None,
577             AvoidRC        = True,
578             Stored         = False,
579             Checked        = False):
580         "Definition d'un concept de calcul"
581         Concept = "ControlModel"
582         self.__case.register("set"+Concept, dir(), locals())
583         self.__adaoObject[Concept] = FullOperator(
584             name             = Concept,
585             asMatrix         = Matrix,
586             asOneFunction    = OneFunction,
587             asThreeFunctions = ThreeFunctions,
588             asScript         = Script,
589             asDict           = Parameters,
590             appliedInX       = None,
591             avoidRC          = AvoidRC,
592             scheduledBy      = Scheduler,
593             toBeChecked      = Checked,
594             )
595         if Stored:
596             self.__StoredInputs[Concept] = self.__adaoObject[Concept].getO()
597         return 0
598
599     def setDebug(self, level = 10):
600         "NOTSET=0 < DEBUG=10 < INFO=20 < WARNING=30 < ERROR=40 < CRITICAL=50"
601         self.__case.register("setDebug",dir(),locals())
602         log = logging.getLogger()
603         log.setLevel( level )
604         self.__StoredInputs["Debug"]   = level
605         self.__StoredInputs["NoDebug"] = False
606         return 0
607
608     def setNoDebug(self):
609         "NOTSET=0 < DEBUG=10 < INFO=20 < WARNING=30 < ERROR=40 < CRITICAL=50"
610         self.__case.register("setNoDebug",dir(),locals())
611         log = logging.getLogger()
612         log.setLevel( logging.WARNING )
613         self.__StoredInputs["Debug"]   = logging.WARNING
614         self.__StoredInputs["NoDebug"] = True
615         return 0
616
617     def setAlgorithmParameters(self,
618             Algorithm  = None,
619             Parameters = None,
620             Script     = None):
621         "Definition d'un concept de calcul"
622         Concept = "AlgorithmParameters"
623         self.__case.register("set"+Concept, dir(), locals())
624         self.__adaoObject[Concept] = AlgorithmAndParameters(
625             name          = Concept,
626             asAlgorithm   = Algorithm,
627             asDict        = Parameters,
628             asScript      = Script,
629             )
630         return 0
631
632     def updateAlgorithmParameters(self,
633             Parameters = None,
634             Script     = None):
635         "Mise a jour d'un concept de calcul"
636         if "AlgorithmParameters" not in self.__adaoObject:
637             raise ValueError("No algorithm registred, ask for one before updating parameters")
638         self.__adaoObject["AlgorithmParameters"].updateParameters(
639             asDict        = Parameters,
640             asScript      = Script,
641             )
642         return 0
643
644     def setObserver(self,
645             Variable       = None,
646             Template       = None,
647             String         = None,
648             Script         = None,
649             ObjectFunction = None,
650             Scheduler      = None,
651             Info           = None):
652         "Definition d'un concept de calcul"
653         Concept = "Observer"
654         self.__case.register("set"+Concept, dir(), locals())
655         self.__adaoObject[Concept].append( DataObserver(
656             name        = Concept,
657             onVariable  = Variable,
658             asTemplate  = Template,
659             asString    = String,
660             asScript    = Script,
661             asObsObject = ObjectFunction,
662             withInfo    = Info,
663             scheduledBy = Scheduler,
664             withAlgo    = self.__adaoObject["AlgorithmParameters"]
665             ))
666         return 0
667
668     def removeObserver(self,
669             Variable       = None,
670             ObjectFunction = None,
671             ):
672         """
673         Permet de retirer un observer à une ou des variable nommée.
674         """
675         if "AlgorithmParameters" not in self.__adaoObject:
676             raise ValueError("No algorithm registred, ask for one before removing observers")
677         #
678         # Vérification du nom de variable et typage
679         # -----------------------------------------
680         if isinstance(Variable, str):
681             VariableNames = (Variable,)
682         elif isinstance(Variable, list):
683             VariableNames = tuple(map( str, Variable ))
684         else:
685             raise ValueError("The observer requires a name or a list of names of variables.")
686         #
687         # Association interne de l'observer à la variable
688         # -----------------------------------------------
689         for ename in VariableNames:
690             if ename not in self.__adaoObject["AlgorithmParameters"]:
691                 raise ValueError("An observer requires to be removed on a variable named %s which does not exist."%ename)
692             else:
693                 return self.__adaoObject["AlgorithmParameters"].removeObserver( ename, ObjectFunction )
694
695     # -----------------------------------------------------------
696
697     def setDiagnostic(self,
698             Diagnostic = None,
699             Identifier = None,
700             Parameters = None,
701             Script     = None,
702             Unit       = None,
703             BaseType   = None):
704         "Definition d'un concept de calcul"
705         Concept = "Diagnostic"
706         self.__case.register("set"+Concept, dir(), locals())
707         self.__adaoObject[Concept].append( DiagnosticAndParameters(
708                  name               = Concept,
709                  asDiagnostic       = Diagnostic,
710                  asIdentifier       = Identifier,
711                  asDict             = Parameters,
712                  asScript           = Script,
713                  asUnit             = Unit,
714                  asBaseType         = BaseType,
715                  asExistingDiags    = self.__StoredInputs[Concept],
716                 ))
717         self.__StoredInputs[Concept].append(str(Identifier))
718         return 0
719
720     def get(self, Concept=None, noDetails=True ):
721         "Recuperation d'une sortie du calcul"
722         """
723         Permet d'accéder aux informations stockées, diagnostics et résultats
724         disponibles après l'exécution du calcul. Attention, quand un diagnostic
725         porte le même nom qu'une variable stockée (paramètre ou résultat),
726         c'est la variable stockée qui est renvoyée, et le diagnostic est
727         inatteignable.
728         """
729         if Concept is not None:
730             try:
731                 self.__case.register("get", dir(), locals(), Concept) # Break pickle in Python 2
732             except:
733                 pass
734             if Concept in self.__StoredInputs:
735                 return self.__StoredInputs[Concept]
736                 #
737             elif self.__adaoObject["AlgorithmParameters"] is not None and Concept == "AlgorithmParameters":
738                 return self.__adaoObject["AlgorithmParameters"].get()
739                 #
740             elif self.__adaoObject["AlgorithmParameters"] is not None and Concept in self.__adaoObject["AlgorithmParameters"]:
741                 return self.__adaoObject["AlgorithmParameters"].get( Concept )
742                 #
743             elif Concept == "AlgorithmRequiredParameters" and self.__adaoObject["AlgorithmParameters"] is not None:
744                 return self.__adaoObject["AlgorithmParameters"].getAlgorithmRequiredParameters(noDetails)
745                 #
746             elif Concept in self.__StoredInputs["Diagnostic"]:
747                 indice = self.__StoredInputs["Diagnostic"].index(Concept)
748                 return self.__adaoObject["Diagnostic"][indice].get()
749                 #
750             else:
751                 raise ValueError("The requested key \"%s\" does not exists as an input, a diagnostic or a stored variable."%Concept)
752         else:
753             allvariables = {}
754             allvariables.update( {"AlgorithmParameters":self.__adaoObject["AlgorithmParameters"].get()} )
755             allvariables.update( self.__adaoObject["AlgorithmParameters"].get() )
756             allvariables.update( self.__StoredInputs )
757             allvariables.pop('Diagnostic', None)
758             allvariables.pop('Observer', None)
759             return allvariables
760
761     # -----------------------------------------------------------
762
763     def get_available_variables(self):
764         """
765         Renvoie les variables potentiellement utilisables pour l'étude,
766         initialement stockées comme données d'entrées ou dans les algorithmes,
767         identifiés par les chaînes de caractères. L'algorithme doit avoir été
768         préalablement choisi sinon la méthode renvoie "None".
769         """
770         if len(list(self.__adaoObject["AlgorithmParameters"].keys())) == 0 and \
771             len(list(self.__StoredInputs.keys())) == 0:
772             return None
773         else:
774             variables = []
775             if len(list(self.__adaoObject["AlgorithmParameters"].keys())) > 0:
776                 variables.extend(list(self.__adaoObject["AlgorithmParameters"].keys()))
777             if len(list(self.__StoredInputs.keys())) > 0:
778                 variables.extend( list(self.__StoredInputs.keys()) )
779             variables.remove('Diagnostic')
780             variables.remove('Observer')
781             variables.sort()
782             return variables
783
784     def get_available_algorithms(self):
785         """
786         Renvoie la liste des algorithmes potentiellement utilisables, identifiés
787         par les chaînes de caractères.
788         """
789         files = []
790         for directory in sys.path:
791             if os.path.isdir(os.path.join(directory,"daAlgorithms")):
792                 for fname in os.listdir(os.path.join(directory,"daAlgorithms")):
793                     root, ext = os.path.splitext(fname)
794                     if ext == '.py' and root != '__init__':
795                         files.append(root)
796         files.sort()
797         return files
798
799     def get_available_diagnostics(self):
800         """
801         Renvoie la liste des diagnostics potentiellement utilisables, identifiés
802         par les chaînes de caractères.
803         """
804         files = []
805         for directory in sys.path:
806             if os.path.isdir(os.path.join(directory,"daDiagnostics")):
807                 for fname in os.listdir(os.path.join(directory,"daDiagnostics")):
808                     root, ext = os.path.splitext(fname)
809                     if ext == '.py' and root != '__init__':
810                         files.append(root)
811         files.sort()
812         return files
813
814     # -----------------------------------------------------------
815
816     def get_algorithms_main_path(self):
817         """
818         Renvoie le chemin pour le répertoire principal contenant les algorithmes
819         dans un sous-répertoire "daAlgorithms"
820         """
821         return self.__parent
822
823     def add_algorithms_path(self, Path=None):
824         """
825         Ajoute au chemin de recherche des algorithmes un répertoire dans lequel
826         se trouve un sous-répertoire "daAlgorithms"
827
828         Remarque : si le chemin a déjà été ajouté pour les diagnostics, il n'est
829         pas indispensable de le rajouter ici.
830         """
831         if not os.path.isdir(Path):
832             raise ValueError("The given "+Path+" argument must exist as a directory")
833         if not os.path.isdir(os.path.join(Path,"daAlgorithms")):
834             raise ValueError("The given \""+Path+"\" argument must contain a subdirectory named \"daAlgorithms\"")
835         if not os.path.isfile(os.path.join(Path,"daAlgorithms","__init__.py")):
836             raise ValueError("The given \""+Path+"/daAlgorithms\" path must contain a file named \"__init__.py\"")
837         sys.path.insert(0, os.path.abspath(Path))
838         sys.path = PlatformInfo.uniq( sys.path ) # Conserve en unique exemplaire chaque chemin
839         return 0
840
841     def get_diagnostics_main_path(self):
842         """
843         Renvoie le chemin pour le répertoire principal contenant les diagnostics
844         dans un sous-répertoire "daDiagnostics"
845         """
846         return self.__parent
847
848     def add_diagnostics_path(self, Path=None):
849         """
850         Ajoute au chemin de recherche des algorithmes un répertoire dans lequel
851         se trouve un sous-répertoire "daDiagnostics"
852
853         Remarque : si le chemin a déjà été ajouté pour les algorithmes, il n'est
854         pas indispensable de le rajouter ici.
855         """
856         if not os.path.isdir(Path):
857             raise ValueError("The given "+Path+" argument must exist as a directory")
858         if not os.path.isdir(os.path.join(Path,"daDiagnostics")):
859             raise ValueError("The given \""+Path+"\" argument must contain a subdirectory named \"daDiagnostics\"")
860         if not os.path.isfile(os.path.join(Path,"daDiagnostics","__init__.py")):
861             raise ValueError("The given \""+Path+"/daDiagnostics\" path must contain a file named \"__init__.py\"")
862         sys.path.insert(0, os.path.abspath(Path))
863         sys.path = PlatformInfo.uniq( sys.path ) # Conserve en unique exemplaire chaque chemin
864         return 0
865
866     # -----------------------------------------------------------
867
868     def execute(self, Executor=None, SaveCaseInFile=None):
869         "Lancement du calcul"
870         self.__case.register("execute",dir(),locals(),None,True)
871         Operator.CM.clearCache()
872         #~ try:
873         if   Executor == "YACS": self.__executeYACSScheme( SaveCaseInFile )
874         else:                    self.__executePythonScheme( SaveCaseInFile )
875         #~ except Exception as e:
876             #~ if isinstance(e, SyntaxError): msg = "at %s: %s"%(e.offset, e.text)
877             #~ else: msg = ""
878             #~ 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))
879         return 0
880
881     def __executePythonScheme(self, FileName=None):
882         "Lancement du calcul"
883         self.__case.register("executePythonScheme", dir(), locals())
884         if FileName is not None:
885             self.dump( FileName, "TUI")
886         self.__adaoObject["AlgorithmParameters"].executePythonScheme( self.__adaoObject )
887         return 0
888
889     def __executeYACSScheme(self, FileName=None):
890         "Lancement du calcul"
891         self.__case.register("executeYACSScheme", dir(), locals())
892         if FileName is not None:
893             self.dump( FileName, "DIC")
894         self.__adaoObject["AlgorithmParameters"].executeYACSScheme( FileName )
895         return 0
896
897     # -----------------------------------------------------------
898
899     def dump(self, FileName=None, Formater="TUI"):
900         "Restitution normalisée des commandes"
901         return self.__case.dump(FileName, Formater)
902
903     def load(self, FileName=None, Formater="TUI"):
904         "Chargement normalisé des commandes"
905         __commands = self.__case.load(FileName, Formater)
906         from numpy import array, matrix
907         for __command in __commands:
908             exec("self."+__command)
909         return 0
910
911     def clear(self):
912         "Effacement du contenu du cas en cours"
913         self.__init__(self.__name)
914
915     # -----------------------------------------------------------
916
917     def __dir__(self):
918         "Clarifie la visibilité des méthodes"
919         return ['set', 'get', 'execute', '__doc__', '__init__', '__module__']
920
921     def prepare_to_pickle(self):
922         "Retire les variables non pickelisables, avec recopie efficace"
923         if self.__adaoObject['AlgorithmParameters'] is not None:
924             for k in self.__adaoObject['AlgorithmParameters'].keys():
925                 if k == "Algorithm": continue
926                 if k in self.__StoredInputs:
927                     raise ValueError("the key \"%s\s to be transfered for pickling will overwrite an existing one.")
928                 if self.__adaoObject['AlgorithmParameters'].hasObserver( k ):
929                     self.__adaoObject['AlgorithmParameters'].removeObserver( k, "", True )
930                 self.__StoredInputs[k] = self.__adaoObject['AlgorithmParameters'].pop(k, None)
931         del self.__adaoObject # Because it breaks pickle in Python 2
932         del self.__case       # Because it breaks pickle in Python 2
933         return 0
934
935 # ==============================================================================
936 if __name__ == "__main__":
937     print('\n AUTODIAGNOSTIC \n')