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