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