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