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