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