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