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