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