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