Salome HOME
Minor documentation improvements
[modules/adao.git] / src / daComposant / daCore / Interfaces.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2021 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     Définit les outils d'interfaces normalisées de cas.
25 """
26 __author__ = "Jean-Philippe ARGAUD"
27 __all__ = []
28
29 import os
30 import sys
31 import numpy
32 import mimetypes
33 import logging
34 import copy
35 from daCore import Persistence
36 from daCore import PlatformInfo
37 from daCore import Templates
38
39 # ==============================================================================
40 class GenericCaseViewer(object):
41     """
42     Gestion des commandes de création d'une vue de cas
43     """
44     def __init__(self, __name="", __objname="case", __content=None, __object=None):
45         "Initialisation et enregistrement de l'entete"
46         self._name         = str(__name)
47         self._objname      = str(__objname)
48         self._lineSerie    = []
49         self._switchoff    = False
50         self._numobservers = 2
51         self._content      = __content
52         self._object       = __object
53         self._missing = """raise ValueError("This case requires beforehand to import or define the variable named <%s>. When corrected, remove this command, correct and uncomment the following one.")\n# """
54     def _append(self, *args):
55         "Transformation d'une commande individuelle en un enregistrement"
56         raise NotImplementedError()
57     def _extract(self, *args):
58         "Transformation d'enregistrement(s) en commande(s) individuelle(s)"
59         raise NotImplementedError()
60     def _finalize(self, __upa=None):
61         "Enregistrement du final"
62         __hasNotExecute = True
63         for l in self._lineSerie:
64             if "%s.execute"%(self._objname,) in l: __hasNotExecute = False
65         if __hasNotExecute:
66             self._lineSerie.append("%s.execute()"%(self._objname,))
67         if __upa is not None and len(__upa)>0:
68             __upa = __upa.replace("ADD.",str(self._objname)+".")
69             self._lineSerie.append(__upa)
70     def _addLine(self, line=""):
71         "Ajoute un enregistrement individuel"
72         self._lineSerie.append(line)
73     def _get_objname(self):
74         return self._objname
75     def dump(self, __filename=None, __upa=None):
76         "Restitution normalisée des commandes"
77         self._finalize(__upa)
78         __text = "\n".join(self._lineSerie)
79         __text +="\n"
80         if __filename is not None:
81             __file = os.path.abspath(__filename)
82             __fid = open(__file,"w")
83             __fid.write(__text)
84             __fid.close()
85         return __text
86     def load(self, __filename=None, __content=None, __object=None):
87         "Chargement normalisé des commandes"
88         if __filename is not None and os.path.exists(__filename):
89             self._content = open(__filename, 'r').read()
90         elif __content is not None and type(__content) is str:
91             self._content = __content
92         elif __object is not None and type(__object) is dict:
93             self._object = copy.deepcopy(__object)
94         else:
95             pass # use "self._content" from initialization
96         __commands = self._extract(self._content, self._object)
97         return __commands
98
99 class _TUIViewer(GenericCaseViewer):
100     """
101     Établissement des commandes d'un cas ADAO TUI (Cas<->TUI)
102     """
103     def __init__(self, __name="", __objname="case", __content=None, __object=None):
104         "Initialisation et enregistrement de l'entete"
105         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
106         self._addLine("# -*- coding: utf-8 -*-")
107         self._addLine("#\n# Python script using ADAO TUI\n#")
108         self._addLine("from numpy import array, matrix")
109         self._addLine("from adao import adaoBuilder")
110         self._addLine("%s = adaoBuilder.New('%s')"%(self._objname, self._name))
111         if self._content is not None:
112             for command in self._content:
113                 self._append(*command)
114     def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
115         "Transformation d'une commande individuelle en un enregistrement"
116         if __command is not None and __keys is not None and __local is not None:
117             if "Concept" in __keys:
118                 logging.debug("TUI Order processed: %s"%(__local["Concept"],))
119             __text  = ""
120             if __pre is not None:
121                 __text += "%s = "%__pre
122             __text += "%s.%s( "%(self._objname,str(__command))
123             if "self" in __keys: __keys.remove("self")
124             if __command not in ("set","get") and "Concept" in __keys: __keys.remove("Concept")
125             for k in __keys:
126                 if k not in __local: continue
127                 __v = __local[k]
128                 if __v is None: continue
129                 if   k == "Checked"              and not __v: continue
130                 if   k == "Stored"               and not __v: continue
131                 if   k == "ColMajor"             and not __v: continue
132                 if   k == "InputFunctionAsMulti" and not __v: continue
133                 if   k == "nextStep"             and not __v: continue
134                 if   k == "AvoidRC"              and     __v: continue
135                 if   k == "noDetails":                        continue
136                 if isinstance(__v,Persistence.Persistence): __v = __v.values()
137                 if callable(__v): __text = self._missing%__v.__name__+__text
138                 if isinstance(__v,dict):
139                     for val in __v.values():
140                         if callable(val): __text = self._missing%val.__name__+__text
141                 numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
142                 __text += "%s=%s, "%(k,repr(__v))
143                 numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
144             __text = __text.rstrip(", ")
145             __text += " )"
146             self._addLine(__text)
147     def _extract(self, __multilines="", __object=None):
148         "Transformation d'enregistrement(s) en commande(s) individuelle(s)"
149         __is_case = False
150         __commands = []
151         __multilines = __multilines.replace("\r\n","\n")
152         for line in __multilines.split("\n"):
153             if "adaoBuilder.New" in line and "=" in line:
154                 self._objname = line.split("=")[0].strip()
155                 __is_case = True
156                 logging.debug("TUI Extracting commands of '%s' object..."%(self._objname,))
157             if not __is_case:
158                 continue
159             else:
160                 if self._objname+".set" in line:
161                     __commands.append( line.replace(self._objname+".","",1) )
162                     logging.debug("TUI Extracted command: %s"%(__commands[-1],))
163         return __commands
164
165 class _COMViewer(GenericCaseViewer):
166     """
167     Établissement des commandes d'un cas COMM (Eficas Native Format/Cas<-COM)
168     """
169     def __init__(self, __name="", __objname="case", __content=None, __object=None):
170         "Initialisation et enregistrement de l'entete"
171         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
172         self._observerIndex = 0
173         self._addLine("# -*- coding: utf-8 -*-")
174         self._addLine("#\n# Python script using ADAO COMM\n#")
175         self._addLine("from numpy import array, matrix")
176         self._addLine("#")
177         self._addLine("%s = {}"%__objname)
178         if self._content is not None:
179             for command in self._content:
180                 self._append(*command)
181     def _extract(self, __multilines=None, __object=None):
182         "Transformation d'enregistrement(s) en commande(s) individuelle(s)"
183         __suppparameters = {}
184         if __multilines is not None:
185             if "ASSIMILATION_STUDY" in __multilines:
186                 __suppparameters.update({'StudyType':"ASSIMILATION_STUDY"})
187                 __multilines = __multilines.replace("ASSIMILATION_STUDY","dict")
188             elif "CHECKING_STUDY" in __multilines:
189                 __suppparameters.update({'StudyType':"CHECKING_STUDY"})
190                 __multilines = __multilines.replace("CHECKING_STUDY",    "dict")
191             else:
192                 __multilines = __multilines.replace("ASSIMILATION_STUDY","dict")
193             #
194             __multilines = __multilines.replace("_F(",               "dict(")
195             __multilines = __multilines.replace(",),);",             ",),)")
196         __fulllines = ""
197         for line in __multilines.split("\n"):
198             if len(line) < 1: continue
199             __fulllines += line + "\n"
200         __multilines = __fulllines
201         self._objname = "case"
202         self._objdata = None
203         exec("self._objdata = "+__multilines)
204         #
205         if self._objdata is None or not(type(self._objdata) is dict) or not('AlgorithmParameters' in self._objdata):
206             raise ValueError("Impossible to load given content as an ADAO COMM one (no dictionnary or no 'AlgorithmParameters' key found).")
207         # ----------------------------------------------------------------------
208         logging.debug("COMM Extracting commands of '%s' object..."%(self._objname,))
209         __commands = []
210         __UserPostAnalysis = ""
211         for k,r in self._objdata.items():
212             __command = k
213             logging.debug("COMM Extracted command: %s:%s"%(k, r))
214             if   __command == "StudyName" and len(str(r))>0:
215                 __commands.append( "set( Concept='Name', String='%s')"%(str(r),) )
216             elif   __command == "StudyRepertory":
217                 __commands.append( "set( Concept='Directory', String='%s')"%(str(r),) )
218             elif   __command == "Debug" and str(r) == "0":
219                 __commands.append( "set( Concept='NoDebug' )" )
220             elif   __command == "Debug" and str(r) == "1":
221                 __commands.append( "set( Concept='Debug' )" )
222             elif   __command == "ExecuteInContainer":
223                 __suppparameters.update({'ExecuteInContainer':r})
224             #
225             elif __command == "UserPostAnalysis" and type(r) is dict:
226                 if 'STRING' in r:
227                     __UserPostAnalysis = r['STRING'].replace("ADD.",str(self._objname)+".")
228                     __commands.append( "set( Concept='UserPostAnalysis', String=\"\"\"%s\"\"\" )"%(__UserPostAnalysis,) )
229                 elif 'SCRIPT_FILE' in r and os.path.exists(r['SCRIPT_FILE']):
230                     __UserPostAnalysis = open(r['SCRIPT_FILE'],'r').read()
231                     __commands.append( "set( Concept='UserPostAnalysis', Script='%s' )"%(r['SCRIPT_FILE'],) )
232                 elif 'Template' in r and not 'ValueTemplate' in r:
233                     # AnalysisPrinter...
234                     if r['Template'] not in Templates.UserPostAnalysisTemplates:
235                         raise ValueError("User post-analysis template \"%s\" does not exist."%(r['Template'],))
236                     else:
237                         __UserPostAnalysis = Templates.UserPostAnalysisTemplates[r['Template']]
238                     __commands.append( "set( Concept='UserPostAnalysis', Template='%s' )"%(r['Template'],) )
239                 elif 'Template' in r and 'ValueTemplate' in r:
240                     # Le template ayant pu être modifié, donc on ne prend que le ValueTemplate...
241                     __UserPostAnalysis = r['ValueTemplate']
242                     __commands.append( "set( Concept='UserPostAnalysis', String=\"\"\"%s\"\"\" )"%(__UserPostAnalysis,) )
243                 else:
244                     __UserPostAnalysis = ""
245             #
246             elif __command == "AlgorithmParameters" and type(r) is dict and 'Algorithm' in r:
247                 if 'data' in r and r['Parameters'] == 'Dict':
248                     __from = r['data']
249                     if 'STRING' in __from:
250                         __parameters = ", Parameters=%s"%(repr(eval(__from['STRING'])),)
251                     elif 'SCRIPT_FILE' in __from and os.path.exists(__from['SCRIPT_FILE']):
252                         __parameters = ", Script='%s'"%(__from['SCRIPT_FILE'],)
253                 else: # if 'Parameters' in r and r['Parameters'] == 'Defaults':
254                     __Dict = copy.deepcopy(r)
255                     __Dict.pop('Algorithm','')
256                     __Dict.pop('Parameters','')
257                     if 'SetSeed' in __Dict:__Dict['SetSeed'] = int(__Dict['SetSeed'])
258                     if 'BoxBounds' in __Dict and type(__Dict['BoxBounds']) is str:
259                         __Dict['BoxBounds'] = eval(__Dict['BoxBounds'])
260                     if len(__Dict) > 0:
261                         __parameters = ', Parameters=%s'%(repr(__Dict),)
262                     else:
263                         __parameters = ""
264                 __commands.append( "set( Concept='AlgorithmParameters', Algorithm='%s'%s )"%(r['Algorithm'],__parameters) )
265             #
266             elif __command == "Observers" and type(r) is dict and 'SELECTION' in r:
267                 if type(r['SELECTION']) is str:
268                     __selection = (r['SELECTION'],)
269                 else:
270                     __selection = tuple(r['SELECTION'])
271                 for sk in __selection:
272                     __idata = r['%s_data'%sk]
273                     if __idata['NodeType'] == 'Template' and 'Template' in __idata:
274                         __template = __idata['Template']
275                         if 'Info' in __idata:
276                             __info = ", Info=\"\"\"%s\"\"\""%(__idata['Info'],)
277                         else:
278                             __info = ""
279                         __commands.append( "set( Concept='Observer', Variable='%s', Template=\"\"\"%s\"\"\"%s )"%(sk,__template,__info) )
280                     if __idata['NodeType'] == 'String' and 'Value' in __idata:
281                         __value =__idata['Value']
282                         __commands.append( "set( Concept='Observer', Variable='%s', String=\"\"\"%s\"\"\" )"%(sk,__value) )
283             #
284             # Background, ObservationError, ObservationOperator...
285             elif type(r) is dict:
286                 __argumentsList = []
287                 if 'Stored' in r and bool(r['Stored']):
288                     __argumentsList.append(['Stored',True])
289                 if 'INPUT_TYPE' in r and 'data' in r:
290                     # Vector, Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, Function
291                     __itype = r['INPUT_TYPE']
292                     __idata = r['data']
293                     if 'FROM' in __idata:
294                         # String, Script, DataFile, Template, ScriptWithOneFunction, ScriptWithFunctions
295                         __ifrom = __idata['FROM']
296                         __idata.pop('FROM','')
297                         if __ifrom == 'String' or __ifrom == 'Template':
298                             __argumentsList.append([__itype,__idata['STRING']])
299                         if __ifrom == 'Script':
300                             __argumentsList.append([__itype,True])
301                             __argumentsList.append(['Script',__idata['SCRIPT_FILE']])
302                         if __ifrom == 'DataFile':
303                             __argumentsList.append([__itype,True])
304                             __argumentsList.append(['DataFile',__idata['DATA_FILE']])
305                         if __ifrom == 'ScriptWithOneFunction':
306                             __argumentsList.append(['OneFunction',True])
307                             __argumentsList.append(['Script',__idata.pop('SCRIPTWITHONEFUNCTION_FILE')])
308                             if len(__idata)>0:
309                                 __argumentsList.append(['Parameters',__idata])
310                         if __ifrom == 'ScriptWithFunctions':
311                             __argumentsList.append(['ThreeFunctions',True])
312                             __argumentsList.append(['Script',__idata.pop('SCRIPTWITHFUNCTIONS_FILE')])
313                             if len(__idata)>0:
314                                 __argumentsList.append(['Parameters',__idata])
315                 __arguments = ["%s = %s"%(k,repr(v)) for k,v in __argumentsList]
316                 __commands.append( "set( Concept='%s', %s )"%(__command, ", ".join(__arguments)))
317         #
318         __commands.append( "set( Concept='%s', Parameters=%s )"%('SupplementaryParameters', repr(__suppparameters)))
319         #
320         # ----------------------------------------------------------------------
321         __commands.sort() # Pour commencer par 'AlgorithmParameters'
322         __commands.append(__UserPostAnalysis)
323         return __commands
324
325 class _SCDViewer(GenericCaseViewer):
326     """
327     Établissement des commandes d'un cas SCD (Study Config Dictionary/Cas->SCD)
328
329     Remarque : le fichier généré est différent de celui obtenu par EFICAS
330     """
331     def __init__(self, __name="", __objname="case", __content=None, __object=None):
332         "Initialisation et enregistrement de l'entête"
333         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
334         #
335         if __content is not None:
336             for command in __content:
337                 if command[0] == "set": __command = command[2]["Concept"]
338                 else:                   __command = command[0].replace("set", "", 1)
339                 if __command == 'Name':
340                     self._name = command[2]["String"]
341         #
342         self.__DebugCommandNotSet = True
343         self.__ObserverCommandNotSet = True
344         self.__UserPostAnalysisNotSet = True
345         #
346         self._addLine("# -*- coding: utf-8 -*-")
347         self._addLine("#\n# Input for ADAO converter to SCD\n#")
348         self._addLine("#")
349         self._addLine("study_config = {}")
350         self._addLine("study_config['Name'] = '%s'"%self._name)
351         self._addLine("#")
352         self._addLine("inputvariables_config = {}")
353         self._addLine("inputvariables_config['Order'] =['adao_default']")
354         self._addLine("inputvariables_config['adao_default'] = -1")
355         self._addLine("study_config['InputVariables'] = inputvariables_config")
356         self._addLine("#")
357         self._addLine("outputvariables_config = {}")
358         self._addLine("outputvariables_config['Order'] = ['adao_default']")
359         self._addLine("outputvariables_config['adao_default'] = -1")
360         self._addLine("study_config['OutputVariables'] = outputvariables_config")
361         if __content is not None:
362             for command in __content:
363                 self._append(*command)
364     def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
365         "Transformation d'une commande individuelle en un enregistrement"
366         if __command == "set": __command = __local["Concept"]
367         else:                  __command = __command.replace("set", "", 1)
368         logging.debug("SCD Order processed: %s"%(__command))
369         #
370         __text  = None
371         if __command in (None, 'execute', 'executePythonScheme', 'executeYACSScheme', 'get', 'Name'):
372             return
373         elif __command in ['Directory',]:
374             __text  = "#\nstudy_config['Repertory'] = %s"%(repr(__local['String']))
375         elif __command in ['Debug', 'setDebug']:
376             __text  = "#\nstudy_config['Debug'] = '1'"
377             self.__DebugCommandNotSet = False
378         elif __command in ['NoDebug', 'setNoDebug']:
379             __text  = "#\nstudy_config['Debug'] = '0'"
380             self.__DebugCommandNotSet = False
381         elif __command in ['Observer', 'setObserver']:
382             if self.__ObserverCommandNotSet:
383                 self._addLine("observers = {}")
384                 self._addLine("study_config['Observers'] = observers")
385                 self.__ObserverCommandNotSet = False
386             __obs   = __local['Variable']
387             self._numobservers += 1
388             __text  = "#\n"
389             __text += "observers['%s'] = {}\n"%__obs
390             if __local['String'] is not None:
391                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
392                 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, __local['String'])
393             if __local['Script'] is not None:
394                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'Script')
395                 __text += "observers['%s']['Script'] = \"%s\"\n"%(__obs, __local['Script'])
396             if __local['Template'] is not None and __local['Template'] in Templates.ObserverTemplates:
397                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
398                 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, Templates.ObserverTemplates[__local['Template']])
399             if __local['Info'] is not None:
400                 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __local['Info'])
401             else:
402                 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __obs)
403             __text += "observers['%s']['number'] = %s"%(__obs, self._numobservers)
404         elif __command in ['UserPostAnalysis', 'setUserPostAnalysis']:
405             __text  = "#\n"
406             __text += "Analysis_config = {}\n"
407             if __local['String'] is not None:
408                 __text += "Analysis_config['From'] = 'String'\n"
409                 __text += "Analysis_config['Data'] = \"\"\"%s\"\"\"\n"%(__local['String'],)
410             if __local['Script'] is not None:
411                 __text += "Analysis_config['From'] = 'Script'\n"
412                 __text += "Analysis_config['Data'] = \"\"\"%s\"\"\"\n"%(__local['Script'],)
413             if __local['Template'] is not None and __local['Template'] in Templates.UserPostAnalysisTemplates:
414                 __text += "Analysis_config['From'] = 'String'\n"
415                 __text += "Analysis_config['Data'] = \"\"\"%s\"\"\"\n"%(Templates.UserPostAnalysisTemplates[__local['Template']],)
416             __text += "study_config['UserPostAnalysis'] = Analysis_config"
417             self.__UserPostAnalysisNotSet = False
418         elif __local is not None: # __keys is not None and
419             numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
420             __text  = "#\n"
421             __text += "%s_config = {}\n"%__command
422             __local.pop('self','')
423             __to_be_removed = []
424             __vectorIsDataFile = False
425             __vectorIsScript = False
426             for __k,__v in __local.items():
427                 if __v is None: __to_be_removed.append(__k)
428             for __k in __to_be_removed:
429                 __local.pop(__k)
430             for __k,__v in __local.items():
431                 if __k == "Concept": continue
432                 if __k in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix','OneFunction','ThreeFunctions'] and 'Script' in __local and __local['Script'] is not None: continue
433                 if __k in ['Vector','VectorSerie'] and 'DataFile' in __local and __local['DataFile'] is not None: continue
434                 if __k == 'Parameters' and not (__command in ['AlgorithmParameters','SupplementaryParameters']): continue
435                 if __k == 'Algorithm':
436                     __text += "study_config['Algorithm'] = %s\n"%(repr(__v))
437                 elif __k == 'DataFile':
438                     __k = 'Vector'
439                     __f = 'DataFile'
440                     __v = "'"+repr(__v)+"'"
441                     for __lk in ['Vector','VectorSerie']:
442                         if __lk in __local and __local[__lk]: __k = __lk
443                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
444                     __text += "%s_config['From'] = '%s'\n"%(__command,__f)
445                     __text += "%s_config['Data'] = %s\n"%(__command,__v)
446                     __text = __text.replace("''","'")
447                     __vectorIsDataFile = True
448                 elif __k == 'Script':
449                     __k = 'Vector'
450                     __f = 'Script'
451                     __v = "'"+repr(__v)+"'"
452                     for __lk in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix']:
453                         if __lk in __local and __local[__lk]: __k = __lk
454                     if __command == "AlgorithmParameters": __k = "Dict"
455                     if 'OneFunction' in __local and __local['OneFunction']:
456                         __text += "%s_ScriptWithOneFunction = {}\n"%(__command,)
457                         __text += "%s_ScriptWithOneFunction['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
458                         __text += "%s_ScriptWithOneFunction['Script'] = {}\n"%(__command,)
459                         __text += "%s_ScriptWithOneFunction['Script']['Direct'] = %s\n"%(__command,__v)
460                         __text += "%s_ScriptWithOneFunction['Script']['Tangent'] = %s\n"%(__command,__v)
461                         __text += "%s_ScriptWithOneFunction['Script']['Adjoint'] = %s\n"%(__command,__v)
462                         __text += "%s_ScriptWithOneFunction['DifferentialIncrement'] = 1e-06\n"%(__command,)
463                         __text += "%s_ScriptWithOneFunction['CenteredFiniteDifference'] = 0\n"%(__command,)
464                         __k = 'Function'
465                         __f = 'ScriptWithOneFunction'
466                         __v = '%s_ScriptWithOneFunction'%(__command,)
467                     if 'ThreeFunctions' in __local and __local['ThreeFunctions']:
468                         __text += "%s_ScriptWithFunctions = {}\n"%(__command,)
469                         __text += "%s_ScriptWithFunctions['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
470                         __text += "%s_ScriptWithFunctions['Script'] = {}\n"%(__command,)
471                         __text += "%s_ScriptWithFunctions['Script']['Direct'] = %s\n"%(__command,__v)
472                         __text += "%s_ScriptWithFunctions['Script']['Tangent'] = %s\n"%(__command,__v)
473                         __text += "%s_ScriptWithFunctions['Script']['Adjoint'] = %s\n"%(__command,__v)
474                         __k = 'Function'
475                         __f = 'ScriptWithFunctions'
476                         __v = '%s_ScriptWithFunctions'%(__command,)
477                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
478                     __text += "%s_config['From'] = '%s'\n"%(__command,__f)
479                     __text += "%s_config['Data'] = %s\n"%(__command,__v)
480                     __text = __text.replace("''","'")
481                     __vectorIsScript = True
482                 elif __k in ('Stored', 'Checked', 'ColMajor', 'InputFunctionAsMulti', 'nextStep'):
483                     if bool(__v):
484                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
485                 elif __k in ('AvoidRC', 'noDetails'):
486                     if not bool(__v):
487                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
488                 else:
489                     if __k == 'Vector' and __vectorIsScript: continue
490                     if __k == 'Vector' and __vectorIsDataFile: continue
491                     if __k == 'Parameters': __k = "Dict"
492                     if isinstance(__v,Persistence.Persistence): __v = __v.values()
493                     if callable(__v): __text = self._missing%__v.__name__+__text
494                     if isinstance(__v,dict):
495                         for val in __v.values():
496                             if callable(val): __text = self._missing%val.__name__+__text
497                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
498                     __text += "%s_config['From'] = '%s'\n"%(__command,'String')
499                     __text += "%s_config['Data'] = \"\"\"%s\"\"\"\n"%(__command,repr(__v))
500             __text += "study_config['%s'] = %s_config"%(__command,__command)
501             numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
502             if __switchoff:
503                 self._switchoff = True
504         if __text is not None: self._addLine(__text)
505         if not __switchoff:
506             self._switchoff = False
507     def _finalize(self, *__args):
508         self.__loadVariablesByScript()
509         if self.__DebugCommandNotSet:
510             self._addLine("#\nstudy_config['Debug'] = '0'")
511         if self.__UserPostAnalysisNotSet:
512             self._addLine("#")
513             self._addLine("Analysis_config = {}")
514             self._addLine("Analysis_config['From'] = 'String'")
515             self._addLine("Analysis_config['Data'] = \"\"\"import numpy")
516             self._addLine("xa=numpy.ravel(ADD.get('Analysis')[-1])")
517             self._addLine("print('Analysis:',xa)\"\"\"")
518             self._addLine("study_config['UserPostAnalysis'] = Analysis_config")
519     def __loadVariablesByScript(self):
520         __ExecVariables = {} # Necessaire pour recuperer la variable
521         exec("\n".join(self._lineSerie), __ExecVariables)
522         study_config = __ExecVariables['study_config']
523         # Pour Python 3 : self.__hasAlgorithm = bool(study_config['Algorithm'])
524         if 'Algorithm' in study_config:
525             self.__hasAlgorithm = True
526         else:
527             self.__hasAlgorithm = False
528         if not self.__hasAlgorithm and \
529                 "AlgorithmParameters" in study_config and \
530                 isinstance(study_config['AlgorithmParameters'], dict) and \
531                 "From" in study_config['AlgorithmParameters'] and \
532                 "Data" in study_config['AlgorithmParameters'] and \
533                 study_config['AlgorithmParameters']['From'] == 'Script':
534             __asScript = study_config['AlgorithmParameters']['Data']
535             __var = ImportFromScript(__asScript).getvalue( "Algorithm" )
536             __text = "#\nstudy_config['Algorithm'] = '%s'"%(__var,)
537             self._addLine(__text)
538         if self.__hasAlgorithm and \
539                 "AlgorithmParameters" in study_config and \
540                 isinstance(study_config['AlgorithmParameters'], dict) and \
541                 "From" not in study_config['AlgorithmParameters'] and \
542                 "Data" not in study_config['AlgorithmParameters']:
543             __text  = "#\n"
544             __text += "AlgorithmParameters_config['Type'] = 'Dict'\n"
545             __text += "AlgorithmParameters_config['From'] = 'String'\n"
546             __text += "AlgorithmParameters_config['Data'] = '{}'\n"
547             self._addLine(__text)
548         if 'SupplementaryParameters' in study_config and \
549                 isinstance(study_config['SupplementaryParameters'], dict) and \
550                 "From" in study_config['SupplementaryParameters'] and \
551                 study_config['SupplementaryParameters']["From"] == 'String' and \
552                 "Data" in study_config['SupplementaryParameters']:
553             __dict = eval(study_config['SupplementaryParameters']["Data"])
554             if 'ExecuteInContainer' in __dict:
555                 self._addLine("#\nstudy_config['ExecuteInContainer'] = '%s'"%__dict['ExecuteInContainer'])
556             else:
557                 self._addLine("#\nstudy_config['ExecuteInContainer'] = 'No'")
558             if 'StudyType' in __dict:
559                 self._addLine("#\nstudy_config['StudyType'] = '%s'"%__dict['StudyType'])
560             if 'StudyType' in __dict and __dict['StudyType'] != "ASSIMILATION_STUDY":
561                 self.__UserPostAnalysisNotSet = False
562         del study_config
563
564 class _YACSViewer(GenericCaseViewer):
565     """
566     Etablissement des commandes d'un cas YACS (Cas->SCD->YACS)
567     """
568     def __init__(self, __name="", __objname="case", __content=None, __object=None):
569         "Initialisation et enregistrement de l'entete"
570         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
571         self.__internalSCD = _SCDViewer(__name, __objname, __content, __object)
572         self._append       = self.__internalSCD._append
573     def dump(self, __filename=None, __upa=None):
574         "Restitution normalisée des commandes"
575         # -----
576         if __filename is None:
577             raise ValueError("A file name has to be given for YACS XML output.")
578         else:
579             __file    = os.path.abspath(__filename)
580             if os.path.isfile(__file) or os.path.islink(__file):
581                 os.remove(__file)
582         # -----
583         if not PlatformInfo.has_salome or \
584             not PlatformInfo.has_adao:
585             raise ImportError(
586                 "Unable to get SALOME or ADAO environnement for YACS conversion.\n"+\
587                 "Please load the right SALOME environnement before trying to use it.")
588         else:
589             from daYacsSchemaCreator.run import create_schema_from_content
590         # -----
591         self.__internalSCD._finalize(__upa)
592         __SCDdump = self.__internalSCD.dump()
593         create_schema_from_content(__SCDdump, __file)
594         # -----
595         if not os.path.exists(__file):
596             __msg  = "An error occured during the ADAO YACS Schema build for\n"
597             __msg += "the target output file:\n"
598             __msg += "  %s\n"%__file
599             __msg += "See errors details in your launching terminal log.\n"
600             raise ValueError(__msg)
601         # -----
602         __fid = open(__file,"r")
603         __text = __fid.read()
604         __fid.close()
605         return __text
606
607 # ==============================================================================
608 class ImportFromScript(object):
609     """
610     Obtention d'une variable nommee depuis un fichier script importé
611     """
612     __slots__ = ("__basename", "__filenspace", "__filestring")
613     def __init__(self, __filename=None):
614         "Verifie l'existence et importe le script"
615         if __filename is None:
616             raise ValueError("The name of the file, containing the variable to be read, has to be specified.")
617         if not os.path.isfile(__filename):
618             raise ValueError("The file containing the variable to be imported doesn't seem to exist. Please check the file. The given file name is:\n  \"%s\""%str(__filename))
619         if os.path.dirname(__filename) != '':
620             sys.path.insert(0, os.path.dirname(__filename))
621             __basename = os.path.basename(__filename).rstrip(".py")
622         else:
623             __basename = __filename.rstrip(".py")
624         PlatformInfo.checkFileNameImportability( __basename+".py" )
625         self.__basename = __basename
626         try:
627             self.__filenspace = __import__(__basename, globals(), locals(), [])
628         except NameError:
629             self.__filenspace = ""
630         with open(__filename,'r') as fid:
631             self.__filestring = fid.read()
632     def getvalue(self, __varname=None, __synonym=None ):
633         "Renvoie la variable demandee par son nom ou son synonyme"
634         if __varname is None:
635             raise ValueError("The name of the variable to be read has to be specified. Please check the content of the file and the syntax.")
636         if not hasattr(self.__filenspace, __varname):
637             if __synonym is None:
638                 raise ValueError("The imported script file \"%s\" doesn't contain the mandatory variable \"%s\" to be read. Please check the content of the file and the syntax."%(str(self.__basename)+".py",__varname))
639             elif not hasattr(self.__filenspace, __synonym):
640                 raise ValueError("The imported script file \"%s\" doesn't contain the mandatory variable \"%s\" to be read. Please check the content of the file and the syntax."%(str(self.__basename)+".py",__synonym))
641             else:
642                 return getattr(self.__filenspace, __synonym)
643         else:
644             return getattr(self.__filenspace, __varname)
645     def getstring(self):
646         "Renvoie le script complet"
647         return self.__filestring
648
649 # ==============================================================================
650 class ImportDetector(object):
651     """
652     Détection des caractéristiques de fichiers ou objets en entrée
653     """
654     __slots__ = (
655         "__url", "__usr", "__root", "__end")
656     def __enter__(self): return self
657     def __exit__(self, exc_type, exc_val, exc_tb): return False
658     #
659     def __init__(self, __url, UserMime=""):
660         if __url is None:
661             raise ValueError("The name or url of the file object has to be specified.")
662         if __url is bytes:
663             self.__url = __url.decode()
664         else:
665             self.__url = str(__url)
666         if UserMime is bytes:
667             self.__usr = UserMime.decode().lower()
668         else:
669             self.__usr = str(UserMime).lower()
670         (self.__root, self.__end) = os.path.splitext(self.__url)
671         #
672         mimetypes.add_type('application/numpy.npy', '.npy')
673         mimetypes.add_type('application/numpy.npz', '.npz')
674         mimetypes.add_type('application/dymola.sdf', '.sdf')
675         if sys.platform.startswith("win"):
676             mimetypes.add_type('text/plain', '.txt')
677             mimetypes.add_type('text/csv', '.csv')
678             mimetypes.add_type('text/tab-separated-values', '.tsv')
679     #
680     # File related tests
681     # ------------------
682     def is_local_file(self):
683         if os.path.isfile(os.path.realpath(self.__url)):
684             return True
685         else:
686             return False
687     def is_not_local_file(self):
688         if not os.path.isfile(os.path.realpath(self.__url)):
689             return True
690         else:
691             return False
692     def raise_error_if_not_local_file(self):
693         if not os.path.isfile(os.path.realpath(self.__url)):
694             raise ValueError("The name or the url of the file object doesn't seem to exist. The given name is:\n  \"%s\""%str(self.__url))
695         else:
696             return False
697     #
698     # Directory related tests
699     # -----------------------
700     def is_local_dir(self):
701         if os.path.isdir(self.__url):
702             return True
703         else:
704             return False
705     def is_not_local_dir(self):
706         if not os.path.isdir(self.__url):
707             return True
708         else:
709             return False
710     def raise_error_if_not_local_dir(self):
711         if not os.path.isdir(self.__url):
712             raise ValueError("The name or the url of the directory object doesn't seem to exist. The given name is:\n  \"%s\""%str(self.__url))
713         else:
714             return False
715     #
716     # Mime related functions
717     # ------------------------
718     def get_standard_mime(self):
719         (__mtype, __encoding) = mimetypes.guess_type(self.__url, strict=False)
720         return __mtype
721     def get_user_mime(self):
722         __fake = "fake."+self.__usr.lower()
723         (__mtype, __encoding) = mimetypes.guess_type(__fake, strict=False)
724         return __mtype
725     def get_comprehensive_mime(self):
726         if self.get_standard_mime() is not None:
727             return self.get_standard_mime()
728         elif self.get_user_mime() is not None:
729             return self.get_user_mime()
730         else:
731             return None
732     #
733     # Name related functions
734     # ----------------------
735     def get_user_name(self):
736         return self.__url
737     def get_absolute_name(self):
738         return os.path.abspath(os.path.realpath(self.__url))
739     def get_extension(self):
740         return self.__end
741
742 class ImportFromFile(object):
743     """
744     Obtention de variables disrétisées en 1D, définies par une ou des variables
745     nommées, et sous la forme d'une série de points éventuellement indexés. La
746     lecture d'un fichier au format spécifié (ou intuité) permet de charger ces
747     fonctions depuis :
748         - des fichiers textes en colonnes de type TXT, CSV, TSV...
749         - des fichiers de données binaires NPY, NPZ, SDF...
750     La lecture du fichier complet ne se fait que si nécessaire, pour assurer la
751     performance tout en disposant de l'interprétation du contenu. Les fichiers
752     textes doivent présenter en première ligne (hors commentaire ou ligne vide)
753     les noms des variables de colonnes. Les commentaires commencent par un "#".
754     """
755     __slots__ = (
756         "_filename", "_colnames", "_colindex", "_varsline", "_format",
757         "_delimiter", "_skiprows", "__url", "__filestring", "__header",
758         "__allowvoid", "__binaryformats", "__supportedformats")
759     def __enter__(self): return self
760     def __exit__(self, exc_type, exc_val, exc_tb): return False
761     #
762     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess", AllowVoidNameList=True):
763         """
764         Verifie l'existence et les informations de définition du fichier. Les
765         noms de colonnes ou de variables sont ignorées si le format ne permet
766         pas de les indiquer.
767         Arguments :
768             - Filename : nom du fichier
769             - ColNames : noms de la ou des colonnes/variables à lire
770             - ColIndex : nom unique de la colonne/variable servant d'index
771             - Format : format du fichier et/ou des données inclues
772             - AllowVoidNameList : permet, si la liste de noms est vide, de
773               prendre par défaut toutes les colonnes
774         """
775         self.__binaryformats =(
776             "application/numpy.npy",
777             "application/numpy.npz",
778             "application/dymola.sdf",
779             )
780         self.__url = ImportDetector( Filename, Format)
781         self.__url.raise_error_if_not_local_file()
782         self._filename = self.__url.get_absolute_name()
783         PlatformInfo.checkFileNameConformity( self._filename )
784         #
785         self._format = self.__url.get_comprehensive_mime()
786         #
787         self.__header, self._varsline, self._skiprows = self.__getentete()
788         #
789         if self._format == "text/csv" or Format.upper() == "CSV":
790             self._format = "text/csv"
791             self.__filestring = "".join(self.__header)
792             if self.__filestring.count(",") > 1:
793                 self._delimiter = ","
794             elif self.__filestring.count(";") > 1:
795                 self._delimiter = ";"
796             else:
797                 self._delimiter = None
798         elif self._format == "text/tab-separated-values" or Format.upper() == "TSV":
799             self._format = "text/tab-separated-values"
800             self._delimiter = "\t"
801         else:
802             self._delimiter = None
803         #
804         if ColNames is not None: self._colnames = tuple(ColNames)
805         else:                    self._colnames = None
806         #
807         if ColIndex is not None: self._colindex = str(ColIndex)
808         else:                    self._colindex = None
809         #
810         self.__allowvoid = bool(AllowVoidNameList)
811
812     def __getentete(self, __nblines = 3):
813         "Lit l'entête du fichier pour trouver la définition des variables"
814         # La première ligne non vide non commentée est toujours considérée
815         # porter les labels de colonne, donc pas des valeurs
816         __header, __varsline, __skiprows = [], "", 1
817         if self._format in self.__binaryformats:
818             pass
819         else:
820             with open(self._filename,'r') as fid:
821                 __line = fid.readline().strip()
822                 while "#" in __line or len(__line) < 1:
823                     __header.append(__line)
824                     __skiprows += 1
825                     __line = fid.readline().strip()
826                 __varsline = __line
827                 for i in range(max(0,__nblines)):
828                     __header.append(fid.readline())
829         return (__header, __varsline, __skiprows)
830
831     def __getindices(self, __colnames, __colindex, __delimiter=None ):
832         "Indices de colonnes correspondants à l'index et aux variables"
833         if __delimiter is None:
834             __varserie = self._varsline.strip('#').strip().split()
835         else:
836             __varserie = self._varsline.strip('#').strip().split(str(__delimiter))
837         #
838         if __colnames is not None:
839             __usecols = []
840             __colnames = tuple(__colnames)
841             for v in __colnames:
842                 for i, n in enumerate(__varserie):
843                     if v == n: __usecols.append(i)
844             __usecols = tuple(__usecols)
845             if len(__usecols) == 0:
846                 if self.__allowvoid:
847                     __usecols = None
848                 else:
849                     raise ValueError("Can not found any column corresponding to the required names %s"%(__colnames,))
850         else:
851             __usecols = None
852         #
853         if __colindex is not None:
854             __useindex = None
855             __colindex = str(__colindex)
856             for i, n in enumerate(__varserie):
857                 if __colindex == n: __useindex = i
858         else:
859             __useindex = None
860         #
861         return (__usecols, __useindex)
862
863     def getsupported(self):
864         self.__supportedformats = {}
865         self.__supportedformats["text/plain"]                = True
866         self.__supportedformats["text/csv"]                  = True
867         self.__supportedformats["text/tab-separated-values"] = True
868         self.__supportedformats["application/numpy.npy"]     = True
869         self.__supportedformats["application/numpy.npz"]     = True
870         self.__supportedformats["application/dymola.sdf"]    = PlatformInfo.has_sdf
871         return self.__supportedformats
872
873     def getvalue(self, ColNames=None, ColIndex=None ):
874         "Renvoie la ou les variables demandees par la liste de leurs noms"
875         # Uniquement si mise à jour
876         if ColNames is not None: self._colnames = tuple(ColNames)
877         if ColIndex is not None: self._colindex = str(ColIndex)
878         #
879         __index = None
880         if self._format == "application/numpy.npy":
881             __columns = numpy.load(self._filename)
882         #
883         elif self._format == "application/numpy.npz":
884             __columns = None
885             with numpy.load(self._filename) as __allcolumns:
886                 if self._colnames is None:
887                     self._colnames = __allcolumns.files
888                 for nom in self._colnames: # Si une variable demandée n'existe pas
889                     if nom not in __allcolumns.files:
890                         self._colnames = tuple( __allcolumns.files )
891                 for nom in self._colnames:
892                     if nom in __allcolumns.files:
893                         if __columns is not None:
894                             # Attention : toutes les variables doivent avoir la même taille
895                             __columns = numpy.vstack((__columns, numpy.reshape(__allcolumns[nom], (1,-1))))
896                         else:
897                             # Première colonne
898                             __columns = numpy.reshape(__allcolumns[nom], (1,-1))
899                 if self._colindex is not None and self._colindex in __allcolumns.files:
900                     __index = numpy.array(numpy.reshape(__allcolumns[self._colindex], (1,-1)), dtype=bytes)
901         elif self._format == "text/plain":
902             __usecols, __useindex = self.__getindices(self._colnames, self._colindex)
903             __columns = numpy.loadtxt(self._filename, usecols = __usecols, skiprows=self._skiprows)
904             if __useindex is not None:
905                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), skiprows=self._skiprows)
906             if __usecols is None: # Si une variable demandée n'existe pas
907                 self._colnames = None
908         #
909         elif self._format == "application/dymola.sdf" and PlatformInfo.has_sdf:
910             import sdf
911             __content = sdf.load(self._filename)
912             __columns = None
913             if self._colnames is None:
914                 self._colnames = [__content.datasets[i].name for i in range(len(__content.datasets))]
915             for nom in self._colnames:
916                 if nom in __content:
917                     if __columns is not None:
918                         # Attention : toutes les variables doivent avoir la même taille
919                         __columns = numpy.vstack((__columns, numpy.reshape(__content[nom].data, (1,-1))))
920                     else:
921                         # Première colonne
922                         __columns = numpy.reshape(__content[nom].data, (1,-1))
923             if self._colindex is not None and self._colindex in __content:
924                 __index = __content[self._colindex].data
925         #
926         elif self._format == "text/csv":
927             __usecols, __useindex = self.__getindices(self._colnames, self._colindex, self._delimiter)
928             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
929             if __useindex is not None:
930                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
931             if __usecols is None: # Si une variable demandée n'existe pas
932                 self._colnames = None
933         #
934         elif self._format == "text/tab-separated-values":
935             __usecols, __useindex = self.__getindices(self._colnames, self._colindex, self._delimiter)
936             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
937             if __useindex is not None:
938                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
939             if __usecols is None: # Si une variable demandée n'existe pas
940                 self._colnames = None
941         else:
942             raise ValueError("Unkown file format \"%s\" or no reader available"%self._format)
943         if __columns is None: __columns = ()
944         #
945         def toString(value):
946             try:
947                 return value.decode()
948             except ValueError:
949                 return value
950         if __index is not None:
951             __index = tuple([toString(v) for v in __index])
952         #
953         return (self._colnames, __columns, self._colindex, __index)
954
955     def getstring(self):
956         "Renvoie le fichier texte complet"
957         if self._format in self.__binaryformats:
958             return ""
959         else:
960             with open(self._filename,'r') as fid:
961                 return fid.read()
962
963     def getformat(self):
964         return self._format
965
966 class ImportScalarLinesFromFile(ImportFromFile):
967     """
968     Importation de fichier contenant des variables scalaires nommées. Le
969     fichier comporte soit 2, soit 4 colonnes, obligatoirement nommées "Name",
970     "Value", "Minimum", "Maximum" si les noms sont précisés. Sur chaque ligne
971     est indiqué le nom, la valeur, et éventuelement deux bornes min et max (ou
972     None si nécessaire pour une borne).
973
974     Seule la méthode "getvalue" est changée.
975     """
976     def __enter__(self): return self
977     def __exit__(self, exc_type, exc_val, exc_tb): return False
978     #
979     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess"):
980         ImportFromFile.__init__(self, Filename, ColNames, ColIndex, Format)
981         if self._format not in ["text/plain", "text/csv", "text/tab-separated-values"]:
982             raise ValueError("Unkown file format \"%s\""%self._format)
983     #
984     def getvalue(self, VarNames = None, HeaderNames=()):
985         "Renvoie la ou les variables demandees par la liste de leurs noms"
986         if VarNames is not None: __varnames = tuple(VarNames)
987         else:                    __varnames = None
988         #
989         if "Name" in self._varsline and "Value" in self._varsline and "Minimum" in self._varsline and "Maximum" in self._varsline:
990             __ftype = "NamValMinMax"
991             __dtypes   = {'names'  : ('Name', 'Value', 'Minimum', 'Maximum'),
992                           'formats': ('S128', 'g', 'g', 'g')}
993             __usecols  = (0, 1, 2, 3)
994             def __replaceNoneN( s ):
995                 if s.strip() == b'None': return numpy.NINF
996                 else:                    return s
997             def __replaceNoneP( s ):
998                 if s.strip() == b'None': return numpy.PINF
999                 else:                    return s
1000             __converters = {2: __replaceNoneN, 3: __replaceNoneP}
1001         elif "Name" in self._varsline and "Value" in self._varsline and ("Minimum" not in self._varsline or "Maximum" not in self._varsline):
1002             __ftype = "NamVal"
1003             __dtypes   = {'names'  : ('Name', 'Value'),
1004                           'formats': ('S128', 'g')}
1005             __converters = None
1006             __usecols  = (0, 1)
1007         elif len(HeaderNames)>0 and numpy.all([kw in self._varsline for kw in HeaderNames]):
1008             __ftype = "NamLotOfVals"
1009             __dtypes   = {'names'  : HeaderNames,
1010                           'formats': tuple(['S128',]+['g']*(len(HeaderNames)-1))}
1011             __usecols  = tuple(range(len(HeaderNames)))
1012             def __replaceNone( s ):
1013                 if s.strip() == b'None': return numpy.NAN
1014                 else:                    return s
1015             __converters = dict()
1016             for i in range(1,len(HeaderNames)):
1017                 __converters[i] = __replaceNone
1018         else:
1019             raise ValueError("Can not find names of columns for initial values. Wrong first line is:\n            \"%s\""%__firstline)
1020         #
1021         if self._format == "text/plain":
1022             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters)
1023         elif self._format in ["text/csv", "text/tab-separated-values"]:
1024             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters, delimiter = self._delimiter)
1025         else:
1026             raise ValueError("Unkown file format \"%s\""%self._format)
1027         #
1028         __names, __thevalue, __bounds = [], [], []
1029         for sub in __content:
1030             if len(__usecols) == 4:
1031                 na, va, mi, ma = sub
1032                 if numpy.isneginf(mi): mi = None # Réattribue les variables None
1033                 elif numpy.isnan(mi):  mi = None # Réattribue les variables None
1034                 if numpy.isposinf(ma): ma = None # Réattribue les variables None
1035                 elif numpy.isnan(ma):  ma = None # Réattribue les variables None
1036             elif len(__usecols) == 2 and __ftype == "NamVal":
1037                 na, va = sub
1038                 mi, ma = None, None
1039             else:
1040                 nsub = list(sub)
1041                 na = sub[0]
1042                 for i, v in enumerate(nsub[1:]):
1043                     if numpy.isnan(v): nsub[i+1] = None
1044                 va = nsub[1:]
1045                 mi, ma = None, None
1046             na = na.decode()
1047             if (__varnames is None or na in __varnames) and (na not in __names):
1048                 # Ne stocke que la premiere occurence d'une variable
1049                 __names.append(na)
1050                 __thevalue.append(va)
1051                 __bounds.append((mi,ma))
1052         #
1053         __names      = tuple(__names)
1054         __thevalue = numpy.array(__thevalue)
1055         __bounds     = tuple(__bounds)
1056         #
1057         return (__names, __thevalue, __bounds)
1058
1059 # ==============================================================================
1060 class EficasGUI(object):
1061     """
1062     Lancement autonome de l'interface EFICAS/ADAO
1063     """
1064     def __init__(self, __addpath = None):
1065         # Chemin pour l'installation (ordre important)
1066         self.__msg = ""
1067         self.__path_settings_ok = False
1068         #----------------
1069         if "EFICAS_ROOT" in os.environ:
1070             __EFICAS_ROOT = os.environ["EFICAS_ROOT"]
1071             __path_ok = True
1072         else:
1073             self.__msg += "\nKeyError:\n"+\
1074                 "  the required environment variable EFICAS_ROOT is unknown.\n"+\
1075                 "  You have either to be in SALOME environment, or to set\n"+\
1076                 "  this variable in your environment to the right path \"<...>\"\n"+\
1077                 "  to find an installed EFICAS application. For example:\n"+\
1078                 "      EFICAS_ROOT=\"<...>\" command\n"
1079             __path_ok = False
1080         try:
1081             import adao
1082             __path_ok = True and __path_ok
1083         except ImportError:
1084             self.__msg += "\nImportError:\n"+\
1085                 "  the required ADAO library can not be found to be imported.\n"+\
1086                 "  You have either to be in ADAO environment, or to be in SALOME\n"+\
1087                 "  environment, or to set manually in your Python 3 environment the\n"+\
1088                 "  right path \"<...>\" to find an installed ADAO application. For\n"+\
1089                 "  example:\n"+\
1090                 "      PYTHONPATH=\"<...>:${PYTHONPATH}\" command\n"
1091             __path_ok = False
1092         try:
1093             import PyQt5
1094             __path_ok = True and __path_ok
1095         except ImportError:
1096             self.__msg += "\nImportError:\n"+\
1097                 "  the required PyQt5 library can not be found to be imported.\n"+\
1098                 "  You have either to have a raisonable up-to-date Python 3\n"+\
1099                 "  installation (less than 5 years), or to be in SALOME environment.\n"
1100             __path_ok = False
1101         #----------------
1102         if not __path_ok:
1103             self.__msg += "\nWarning:\n"+\
1104                 "  It seems you have some troubles with your installation.\n"+\
1105                 "  Be aware that some other errors may exist, that are not\n"+\
1106                 "  explained as above, like some incomplete or obsolete\n"+\
1107                 "  Python 3, or incomplete module installation.\n"+\
1108                 "  \n"+\
1109                 "  Please correct the above error(s) before launching the\n"+\
1110                 "  standalone EFICAS/ADAO interface.\n"
1111             logging.debug("Some of the ADAO/EFICAS/QT5 paths have not been found")
1112             self.__path_settings_ok = False
1113         else:
1114             logging.debug("All the ADAO/EFICAS/QT5 paths have been found")
1115             self.__path_settings_ok = True
1116         #----------------
1117         if self.__path_settings_ok:
1118             sys.path.insert(0,__EFICAS_ROOT)
1119             sys.path.insert(0,os.path.join(adao.adao_py_dir,"daEficas"))
1120             if __addpath is not None and os.path.exists(os.path.abspath(__addpath)):
1121                 sys.path.insert(0,os.path.abspath(__addpath))
1122             logging.debug("All the paths have been correctly set up")
1123         else:
1124             print(self.__msg)
1125             logging.debug("Errors in path settings have been found")
1126
1127     def gui(self):
1128         if self.__path_settings_ok:
1129             logging.debug("Launching standalone EFICAS/ADAO interface...")
1130             from daEficas import prefs
1131             from InterfaceQT4 import eficas_go
1132             eficas_go.lanceEficas(code=prefs.code)
1133         else:
1134             logging.debug("Can not launch standalone EFICAS/ADAO interface for path errors.")
1135
1136 # ==============================================================================
1137 if __name__ == "__main__":
1138     print('\n AUTODIAGNOSTIC\n')