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