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