Salome HOME
Code improvements for warning on iteration control
[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 not 'ValueTemplate' 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'] and 'Script' in __local and __local['Script'] is not None: continue
457                 if __k in ['Vector','VectorSerie'] and 'DataFile' in __local and __local['DataFile'] is not None: continue
458                 if __k == 'Parameters' and not (__command in ['AlgorithmParameters','SupplementaryParameters']): continue
459                 if __k == 'Algorithm':
460                     __text += "study_config['Algorithm'] = %s\n"%(repr(__v))
461                 elif __k == 'DataFile':
462                     __k = 'Vector'
463                     __f = 'DataFile'
464                     __v = "'"+repr(__v)+"'"
465                     for __lk in ['Vector','VectorSerie']:
466                         if __lk in __local and __local[__lk]: __k = __lk
467                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
468                     __text += "%s_config['From'] = '%s'\n"%(__command,__f)
469                     __text += "%s_config['Data'] = %s\n"%(__command,__v)
470                     __text = __text.replace("''","'")
471                     __vectorIsDataFile = True
472                 elif __k == 'Script':
473                     __k = 'Vector'
474                     __f = 'Script'
475                     __v = "'"+repr(__v)+"'"
476                     for __lk in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix']:
477                         if __lk in __local and __local[__lk]: __k = __lk
478                     if __command == "AlgorithmParameters": __k = "Dict"
479                     if 'OneFunction' in __local and __local['OneFunction']:
480                         __text += "%s_ScriptWithOneFunction = {}\n"%(__command,)
481                         __text += "%s_ScriptWithOneFunction['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
482                         __text += "%s_ScriptWithOneFunction['Script'] = {}\n"%(__command,)
483                         __text += "%s_ScriptWithOneFunction['Script']['Direct'] = %s\n"%(__command,__v)
484                         __text += "%s_ScriptWithOneFunction['Script']['Tangent'] = %s\n"%(__command,__v)
485                         __text += "%s_ScriptWithOneFunction['Script']['Adjoint'] = %s\n"%(__command,__v)
486                         __text += "%s_ScriptWithOneFunction['DifferentialIncrement'] = 1e-06\n"%(__command,)
487                         __text += "%s_ScriptWithOneFunction['CenteredFiniteDifference'] = 0\n"%(__command,)
488                         __k = 'Function'
489                         __f = 'ScriptWithOneFunction'
490                         __v = '%s_ScriptWithOneFunction'%(__command,)
491                     if 'ThreeFunctions' in __local and __local['ThreeFunctions']:
492                         __text += "%s_ScriptWithFunctions = {}\n"%(__command,)
493                         __text += "%s_ScriptWithFunctions['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
494                         __text += "%s_ScriptWithFunctions['Script'] = {}\n"%(__command,)
495                         __text += "%s_ScriptWithFunctions['Script']['Direct'] = %s\n"%(__command,__v)
496                         __text += "%s_ScriptWithFunctions['Script']['Tangent'] = %s\n"%(__command,__v)
497                         __text += "%s_ScriptWithFunctions['Script']['Adjoint'] = %s\n"%(__command,__v)
498                         __k = 'Function'
499                         __f = 'ScriptWithFunctions'
500                         __v = '%s_ScriptWithFunctions'%(__command,)
501                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
502                     __text += "%s_config['From'] = '%s'\n"%(__command,__f)
503                     __text += "%s_config['Data'] = %s\n"%(__command,__v)
504                     __text = __text.replace("''","'")
505                     __vectorIsScript = True
506                 elif __k in ('Stored', 'Checked', 'ColMajor', 'InputFunctionAsMulti', 'nextStep'):
507                     if bool(__v):
508                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
509                 elif __k in ('PerformanceProfile', 'noDetails'):
510                     if not bool(__v):
511                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
512                 else:
513                     if __k == 'Vector' and __vectorIsScript: continue
514                     if __k == 'Vector' and __vectorIsDataFile: continue
515                     if __k == 'Parameters': __k = "Dict"
516                     if isinstance(__v,Persistence.Persistence): __v = __v.values()
517                     if callable(__v): __text = self._missing%__v.__name__+__text
518                     if isinstance(__v,dict):
519                         for val in __v.values():
520                             if callable(val): __text = self._missing%val.__name__+__text
521                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
522                     __text += "%s_config['From'] = '%s'\n"%(__command,'String')
523                     __text += "%s_config['Data'] = \"\"\"%s\"\"\"\n"%(__command,repr(__v))
524             __text += "study_config['%s'] = %s_config"%(__command,__command)
525             numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
526             if __switchoff:
527                 self._switchoff = True
528         if __text is not None: self._addLine(__text)
529         if not __switchoff:
530             self._switchoff = False
531     def _finalize(self, *__args):
532         self.__loadVariablesByScript()
533         if self.__DebugCommandNotSet:
534             self._addLine("#\nstudy_config['Debug'] = '0'")
535         if self.__UserPostAnalysisNotSet:
536             self._addLine("#")
537             self._addLine("Analysis_config = {}")
538             self._addLine("Analysis_config['From'] = 'String'")
539             self._addLine("Analysis_config['Data'] = \"\"\"import numpy")
540             self._addLine("xa=ADD.get('Analysis')[-1]")
541             self._addLine("print('Analysis:',xa)\"\"\"")
542             self._addLine("study_config['UserPostAnalysis'] = Analysis_config")
543     def __loadVariablesByScript(self):
544         __ExecVariables = {} # Necessaire pour recuperer la variable
545         exec("\n".join(self._lineSerie), __ExecVariables)
546         study_config = __ExecVariables['study_config']
547         # Pour Python 3 : self.__hasAlgorithm = bool(study_config['Algorithm'])
548         if 'Algorithm' in study_config:
549             self.__hasAlgorithm = True
550         else:
551             self.__hasAlgorithm = False
552         if not self.__hasAlgorithm and \
553                 "AlgorithmParameters" in study_config and \
554                 isinstance(study_config['AlgorithmParameters'], dict) and \
555                 "From" in study_config['AlgorithmParameters'] and \
556                 "Data" in study_config['AlgorithmParameters'] and \
557                 study_config['AlgorithmParameters']['From'] == 'Script':
558             __asScript = study_config['AlgorithmParameters']['Data']
559             __var = ImportFromScript(__asScript).getvalue( "Algorithm" )
560             __text = "#\nstudy_config['Algorithm'] = '%s'"%(__var,)
561             self._addLine(__text)
562         if self.__hasAlgorithm and \
563                 "AlgorithmParameters" in study_config and \
564                 isinstance(study_config['AlgorithmParameters'], dict) and \
565                 "From" not in study_config['AlgorithmParameters'] and \
566                 "Data" not in study_config['AlgorithmParameters']:
567             __text  = "#\n"
568             __text += "AlgorithmParameters_config['Type'] = 'Dict'\n"
569             __text += "AlgorithmParameters_config['From'] = 'String'\n"
570             __text += "AlgorithmParameters_config['Data'] = '{}'\n"
571             self._addLine(__text)
572         if 'SupplementaryParameters' in study_config and \
573                 isinstance(study_config['SupplementaryParameters'], dict) and \
574                 "From" in study_config['SupplementaryParameters'] and \
575                 study_config['SupplementaryParameters']["From"] == 'String' and \
576                 "Data" in study_config['SupplementaryParameters']:
577             __dict = eval(study_config['SupplementaryParameters']["Data"])
578             if 'ExecuteInContainer' in __dict:
579                 self._addLine("#\nstudy_config['ExecuteInContainer'] = '%s'"%__dict['ExecuteInContainer'])
580             else:
581                 self._addLine("#\nstudy_config['ExecuteInContainer'] = 'No'")
582             if 'StudyType' in __dict:
583                 self._addLine("#\nstudy_config['StudyType'] = '%s'"%__dict['StudyType'])
584             if 'StudyType' in __dict and __dict['StudyType'] != "ASSIMILATION_STUDY":
585                 self.__UserPostAnalysisNotSet = False
586         del study_config
587
588 class _YACSViewer(GenericCaseViewer):
589     """
590     Etablissement des commandes d'un cas YACS (Cas->SCD->YACS)
591     """
592     def __init__(self, __name="", __objname="case", __content=None, __object=None):
593         "Initialisation et enregistrement de l'entete"
594         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
595         self.__internalSCD = _SCDViewer(__name, __objname, __content, __object)
596         self._append       = self.__internalSCD._append
597     def dump(self, __filename=None, __upa=None):
598         "Restitution normalisée des commandes"
599         # -----
600         if __filename is None:
601             raise ValueError("A file name has to be given for YACS XML output.")
602         else:
603             __file    = os.path.abspath(__filename)
604             if os.path.isfile(__file) or os.path.islink(__file):
605                 os.remove(__file)
606         # -----
607         if not PlatformInfo.has_salome or \
608             not PlatformInfo.has_adao:
609             raise ImportError(
610                 "Unable to get SALOME or ADAO environnement for YACS conversion.\n"+\
611                 "Please load the right SALOME environnement before trying to use it.")
612         else:
613             from daYacsSchemaCreator.run import create_schema_from_content
614         # -----
615         self.__internalSCD._finalize(__upa)
616         __SCDdump = self.__internalSCD.dump()
617         create_schema_from_content(__SCDdump, __file)
618         # -----
619         if not os.path.exists(__file):
620             __msg  = "An error occured during the ADAO YACS Schema build for\n"
621             __msg += "the target output file:\n"
622             __msg += "  %s\n"%__file
623             __msg += "See errors details in your launching terminal log.\n"
624             raise ValueError(__msg)
625         # -----
626         __fid = open(__file,"r")
627         __text = __fid.read()
628         __fid.close()
629         return __text
630
631 # ==============================================================================
632 class _ReportViewer(GenericCaseViewer):
633     """
634     Partie commune de restitution simple
635     """
636     def __init__(self, __name="", __objname="case", __content=None, __object=None):
637         "Initialisation et enregistrement de l'entete"
638         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
639         self._r = Reporting.ReportStorage()
640         self._r.clear()
641         if self._name == "":
642             self._r.append("ADAO Study report", "title")
643         else:
644             self._r.append(str(self._name), "title")
645         if self._content is not None:
646             for command in self._content:
647                 self._append(*command)
648     def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
649         "Transformation d'une commande individuelle en un enregistrement"
650         if __command is not None and __keys is not None and __local is not None:
651             if __command in ("set","get") and "Concept" in __keys: __command = __local["Concept"]
652             __text  = ""
653             __text += "<i>%s</i> command has been set"%str(__command.replace("set",""))
654             __ktext = ""
655             for k in __keys:
656                 if k not in __local: continue
657                 __v = __local[k]
658                 if __v is None: continue
659                 if   k == "Checked"              and not __v: continue
660                 if   k == "Stored"               and not __v: continue
661                 if   k == "ColMajor"             and not __v: continue
662                 if   k == "InputFunctionAsMulti" and not __v: continue
663                 if   k == "nextStep"             and not __v: continue
664                 if   k == "PerformanceProfile"   and     __v: continue
665                 if   k == "noDetails":                        continue
666                 if   k == "Concept":                          continue
667                 if   k == "self":                             continue
668                 if isinstance(__v,Persistence.Persistence): __v = __v.values()
669                 numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
670                 __ktext += "\n        %s = %s,"%(k,repr(__v))
671                 numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
672             if len(__ktext) > 0:
673                 __text += " with values:" + __ktext
674             __text = __text.rstrip(", ")
675             self._r.append(__text, "uli")
676     def _finalize(self, __upa=None):
677         "Enregistrement du final"
678         raise NotImplementedError()
679
680 class _SimpleReportInRstViewer(_ReportViewer):
681     """
682     Restitution simple en RST
683     """
684     def _finalize(self, __upa=None):
685         self._lineSerie.append(Reporting.ReportViewInRst(self._r).__str__())
686
687 class _SimpleReportInHtmlViewer(_ReportViewer):
688     """
689     Restitution simple en HTML
690     """
691     def _finalize(self, __upa=None):
692         self._lineSerie.append(Reporting.ReportViewInHtml(self._r).__str__())
693
694 class _SimpleReportInPlainTxtViewer(_ReportViewer):
695     """
696     Restitution simple en TXT
697     """
698     def _finalize(self, __upa=None):
699         self._lineSerie.append(Reporting.ReportViewInPlainTxt(self._r).__str__())
700
701 # ==============================================================================
702 class ImportFromScript(object):
703     """
704     Obtention d'une variable nommee depuis un fichier script importé
705     """
706     __slots__ = ("__basename", "__filenspace", "__filestring")
707     def __init__(self, __filename=None):
708         "Verifie l'existence et importe le script"
709         if __filename is None:
710             raise ValueError("The name of the file, containing the variable to be read, has to be specified.")
711         if not os.path.isfile(__filename):
712             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))
713         if os.path.dirname(__filename) != '':
714             sys.path.insert(0, os.path.dirname(__filename))
715             __basename = os.path.basename(__filename).rstrip(".py")
716         else:
717             __basename = __filename.rstrip(".py")
718         PlatformInfo.checkFileNameImportability( __basename+".py" )
719         self.__basename = __basename
720         try:
721             self.__filenspace = __import__(__basename, globals(), locals(), [])
722         except NameError:
723             self.__filenspace = ""
724         with open(__filename,'r') as fid:
725             self.__filestring = fid.read()
726     def getvalue(self, __varname=None, __synonym=None ):
727         "Renvoie la variable demandee par son nom ou son synonyme"
728         if __varname is None:
729             raise ValueError("The name of the variable to be read has to be specified. Please check the content of the file and the syntax.")
730         if not hasattr(self.__filenspace, __varname):
731             if __synonym is None:
732                 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))
733             elif not hasattr(self.__filenspace, __synonym):
734                 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))
735             else:
736                 return getattr(self.__filenspace, __synonym)
737         else:
738             return getattr(self.__filenspace, __varname)
739     def getstring(self):
740         "Renvoie le script complet"
741         return self.__filestring
742
743 # ==============================================================================
744 class ImportDetector(object):
745     """
746     Détection des caractéristiques de fichiers ou objets en entrée
747     """
748     __slots__ = (
749         "__url", "__usr", "__root", "__end")
750     def __enter__(self): return self
751     def __exit__(self, exc_type, exc_val, exc_tb): return False
752     #
753     def __init__(self, __url, UserMime=""):
754         if __url is None:
755             raise ValueError("The name or url of the file object has to be specified.")
756         if __url is bytes:
757             self.__url = __url.decode()
758         else:
759             self.__url = str(__url)
760         if UserMime is bytes:
761             self.__usr = UserMime.decode().lower()
762         else:
763             self.__usr = str(UserMime).lower()
764         (self.__root, self.__end) = os.path.splitext(self.__url)
765         #
766         mimetypes.add_type('application/numpy.npy', '.npy')
767         mimetypes.add_type('application/numpy.npz', '.npz')
768         mimetypes.add_type('application/dymola.sdf', '.sdf')
769         if sys.platform.startswith("win"):
770             mimetypes.add_type('text/plain', '.txt')
771             mimetypes.add_type('text/csv', '.csv')
772             mimetypes.add_type('text/tab-separated-values', '.tsv')
773     #
774     # File related tests
775     # ------------------
776     def is_local_file(self):
777         if os.path.isfile(os.path.realpath(self.__url)):
778             return True
779         else:
780             return False
781     def is_not_local_file(self):
782         return not self.is_local_file()
783     def raise_error_if_not_local_file(self):
784         if self.is_not_local_file():
785             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))
786         else:
787             return False
788     #
789     # Directory related tests
790     # -----------------------
791     def is_local_dir(self):
792         if os.path.isdir(self.__url):
793             return True
794         else:
795             return False
796     def is_not_local_dir(self):
797         return not self.is_local_dir()
798     def raise_error_if_not_local_dir(self):
799         if self.is_not_local_dir():
800             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))
801         else:
802             return False
803     #
804     # Mime related functions
805     # ------------------------
806     def get_standard_mime(self):
807         (__mtype, __encoding) = mimetypes.guess_type(self.__url, strict=False)
808         return __mtype
809     def get_user_mime(self):
810         __fake = "fake."+self.__usr.lower()
811         (__mtype, __encoding) = mimetypes.guess_type(__fake, strict=False)
812         return __mtype
813     def get_comprehensive_mime(self):
814         if self.get_standard_mime() is not None:
815             return self.get_standard_mime()
816         elif self.get_user_mime() is not None:
817             return self.get_user_mime()
818         else:
819             return None
820     #
821     # Name related functions
822     # ----------------------
823     def get_user_name(self):
824         return self.__url
825     def get_absolute_name(self):
826         return os.path.abspath(os.path.realpath(self.__url))
827     def get_extension(self):
828         return self.__end
829
830 class ImportFromFile(object):
831     """
832     Obtention de variables disrétisées en 1D, définies par une ou des variables
833     nommées, et sous la forme d'une série de points éventuellement indexés. La
834     lecture d'un fichier au format spécifié (ou intuité) permet de charger ces
835     fonctions depuis :
836         - des fichiers textes en colonnes de type TXT, CSV, TSV...
837         - des fichiers de données binaires NPY, NPZ, SDF...
838     La lecture du fichier complet ne se fait que si nécessaire, pour assurer la
839     performance tout en disposant de l'interprétation du contenu. Les fichiers
840     textes doivent présenter en première ligne (hors commentaire ou ligne vide)
841     les noms des variables de colonnes. Les commentaires commencent par un "#".
842     """
843     __slots__ = (
844         "_filename", "_colnames", "_colindex", "_varsline", "_format",
845         "_delimiter", "_skiprows", "__url", "__filestring", "__header",
846         "__allowvoid", "__binaryformats", "__supportedformats")
847     def __enter__(self): return self
848     def __exit__(self, exc_type, exc_val, exc_tb): return False
849     #
850     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess", AllowVoidNameList=True):
851         """
852         Verifie l'existence et les informations de définition du fichier. Les
853         noms de colonnes ou de variables sont ignorées si le format ne permet
854         pas de les indiquer.
855         Arguments :
856             - Filename : nom du fichier
857             - ColNames : noms de la ou des colonnes/variables à lire
858             - ColIndex : nom unique de la colonne/variable servant d'index
859             - Format : format du fichier et/ou des données inclues
860             - AllowVoidNameList : permet, si la liste de noms est vide, de
861               prendre par défaut toutes les colonnes
862         """
863         self.__binaryformats =(
864             "application/numpy.npy",
865             "application/numpy.npz",
866             "application/dymola.sdf",
867             )
868         self.__url = ImportDetector( Filename, Format)
869         self.__url.raise_error_if_not_local_file()
870         self._filename = self.__url.get_absolute_name()
871         PlatformInfo.checkFileNameConformity( self._filename )
872         #
873         self._format = self.__url.get_comprehensive_mime()
874         #
875         self.__header, self._varsline, self._skiprows = self.__getentete()
876         #
877         if self._format == "text/csv" or Format.upper() == "CSV":
878             self._format = "text/csv"
879             self.__filestring = "".join(self.__header)
880             if self.__filestring.count(",") > 1:
881                 self._delimiter = ","
882             elif self.__filestring.count(";") > 1:
883                 self._delimiter = ";"
884             else:
885                 self._delimiter = None
886         elif self._format == "text/tab-separated-values" or Format.upper() == "TSV":
887             self._format = "text/tab-separated-values"
888             self._delimiter = "\t"
889         else:
890             self._delimiter = None
891         #
892         if ColNames is not None: self._colnames = tuple(ColNames)
893         else:                    self._colnames = None
894         #
895         if ColIndex is not None: self._colindex = str(ColIndex)
896         else:                    self._colindex = None
897         #
898         self.__allowvoid = bool(AllowVoidNameList)
899
900     def __getentete(self, __nblines = 3):
901         "Lit l'entête du fichier pour trouver la définition des variables"
902         # La première ligne non vide non commentée est toujours considérée
903         # porter les labels de colonne, donc pas des valeurs
904         __header, __varsline, __skiprows = [], "", 1
905         if self._format in self.__binaryformats:
906             pass
907         else:
908             with open(self._filename,'r') as fid:
909                 __line = fid.readline().strip()
910                 while "#" in __line or len(__line) < 1:
911                     __header.append(__line)
912                     __skiprows += 1
913                     __line = fid.readline().strip()
914                 __varsline = __line # Ligne de labels par convention
915                 for i in range(max(0,__nblines)):
916                     __header.append(fid.readline())
917         return (__header, __varsline, __skiprows)
918
919     def __getindices(self, __colnames, __colindex, __delimiter=None ):
920         "Indices de colonnes correspondants à l'index et aux variables"
921         if __delimiter is None:
922             __varserie = self._varsline.strip('#').strip().split()
923         else:
924             __varserie = self._varsline.strip('#').strip().split(str(__delimiter))
925         #
926         if __colnames is not None:
927             __usecols = []
928             __colnames = tuple(__colnames)
929             for v in __colnames:
930                 for i, n in enumerate(__varserie):
931                     if v == n: __usecols.append(i)
932             __usecols = tuple(__usecols)
933             if len(__usecols) == 0:
934                 if self.__allowvoid:
935                     __usecols = None
936                 else:
937                     raise ValueError("Can not found any column corresponding to the required names %s"%(__colnames,))
938         else:
939             __usecols = None
940         #
941         if __colindex is not None:
942             __useindex = None
943             __colindex = str(__colindex)
944             for i, n in enumerate(__varserie):
945                 if __colindex == n: __useindex = i
946         else:
947             __useindex = None
948         #
949         return (__usecols, __useindex)
950
951     def getsupported(self):
952         self.__supportedformats = {}
953         self.__supportedformats["text/plain"]                = True
954         self.__supportedformats["text/csv"]                  = True
955         self.__supportedformats["text/tab-separated-values"] = True
956         self.__supportedformats["application/numpy.npy"]     = True
957         self.__supportedformats["application/numpy.npz"]     = True
958         self.__supportedformats["application/dymola.sdf"]    = PlatformInfo.has_sdf
959         return self.__supportedformats
960
961     def getvalue(self, ColNames=None, ColIndex=None ):
962         "Renvoie la ou les variables demandées par la liste de leurs noms"
963         # Uniquement si mise à jour
964         if ColNames is not None: self._colnames = tuple(ColNames)
965         if ColIndex is not None: self._colindex = str(ColIndex)
966         #
967         __index = None
968         if self._format == "application/numpy.npy":
969             __columns = numpy.load(self._filename)
970         #
971         elif self._format == "application/numpy.npz":
972             __columns = None
973             with numpy.load(self._filename) as __allcolumns:
974                 if self._colnames is None:
975                     self._colnames = __allcolumns.files
976                 for nom in self._colnames: # Si une variable demandée n'existe pas
977                     if nom not in __allcolumns.files:
978                         self._colnames = tuple( __allcolumns.files )
979                 for nom in self._colnames:
980                     if nom in __allcolumns.files:
981                         if __columns is not None:
982                             # Attention : toutes les variables doivent avoir la même taille
983                             __columns = numpy.vstack((__columns, numpy.reshape(__allcolumns[nom], (1,-1))))
984                         else:
985                             # Première colonne
986                             __columns = numpy.reshape(__allcolumns[nom], (1,-1))
987                 if self._colindex is not None and self._colindex in __allcolumns.files:
988                     __index = numpy.array(numpy.reshape(__allcolumns[self._colindex], (1,-1)), dtype=bytes)
989         elif self._format == "text/plain":
990             __usecols, __useindex = self.__getindices(self._colnames, self._colindex)
991             __columns = numpy.loadtxt(self._filename, usecols = __usecols, skiprows=self._skiprows)
992             if __useindex is not None:
993                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), skiprows=self._skiprows)
994             if __usecols is None: # Si une variable demandée n'existe pas
995                 self._colnames = None
996         #
997         elif self._format == "application/dymola.sdf" and PlatformInfo.has_sdf:
998             import sdf
999             __content = sdf.load(self._filename)
1000             __columns = None
1001             if self._colnames is None:
1002                 self._colnames = [__content.datasets[i].name for i in range(len(__content.datasets))]
1003             for nom in self._colnames:
1004                 if nom in __content:
1005                     if __columns is not None:
1006                         # Attention : toutes les variables doivent avoir la même taille
1007                         __columns = numpy.vstack((__columns, numpy.reshape(__content[nom].data, (1,-1))))
1008                     else:
1009                         # Première colonne
1010                         __columns = numpy.reshape(__content[nom].data, (1,-1))
1011             if self._colindex is not None and self._colindex in __content:
1012                 __index = __content[self._colindex].data
1013         #
1014         elif self._format == "text/csv":
1015             __usecols, __useindex = self.__getindices(self._colnames, self._colindex, self._delimiter)
1016             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
1017             if __useindex is not None:
1018                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
1019             if __usecols is None: # Si une variable demandée n'existe pas
1020                 self._colnames = None
1021         #
1022         elif self._format == "text/tab-separated-values":
1023             __usecols, __useindex = self.__getindices(self._colnames, self._colindex, self._delimiter)
1024             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
1025             if __useindex is not None:
1026                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
1027             if __usecols is None: # Si une variable demandée n'existe pas
1028                 self._colnames = None
1029         else:
1030             raise ValueError("Unkown file format \"%s\" or no reader available"%self._format)
1031         if __columns is None: __columns = ()
1032         #
1033         def toString(value):
1034             try:
1035                 return value.decode()
1036             except ValueError:
1037                 return value
1038         if __index is not None:
1039             __index = tuple([toString(v) for v in __index])
1040         #
1041         return (self._colnames, __columns, self._colindex, __index)
1042
1043     def getstring(self):
1044         "Renvoie le fichier texte complet"
1045         if self._format in self.__binaryformats:
1046             return ""
1047         else:
1048             with open(self._filename,'r') as fid:
1049                 return fid.read()
1050
1051     def getformat(self):
1052         return self._format
1053
1054 class ImportScalarLinesFromFile(ImportFromFile):
1055     """
1056     Importation de fichier contenant des variables scalaires nommées. Le
1057     fichier comporte soit 2, soit 4 colonnes, obligatoirement nommées "Name",
1058     "Value", "Minimum", "Maximum" si les noms sont précisés. Sur chaque ligne
1059     est indiqué le nom, la valeur, et éventuelement deux bornes min et max (ou
1060     None si nécessaire pour une borne).
1061
1062     Seule la méthode "getvalue" est changée.
1063     """
1064     def __enter__(self): return self
1065     def __exit__(self, exc_type, exc_val, exc_tb): return False
1066     #
1067     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess"):
1068         ImportFromFile.__init__(self, Filename, ColNames, ColIndex, Format)
1069         if self._format not in ["text/plain", "text/csv", "text/tab-separated-values"]:
1070             raise ValueError("Unkown file format \"%s\""%self._format)
1071     #
1072     def getvalue(self, VarNames = None, HeaderNames=()):
1073         "Renvoie la ou les variables demandées par la liste de leurs noms"
1074         if VarNames is not None: __varnames = tuple(VarNames)
1075         else:                    __varnames = None
1076         #
1077         if "Name" in self._varsline and "Value" in self._varsline and "Minimum" in self._varsline and "Maximum" in self._varsline:
1078             __ftype = "NamValMinMax"
1079             __dtypes   = {'names'  : ('Name', 'Value', 'Minimum', 'Maximum'),
1080                           'formats': ('S128', 'g', 'g', 'g')}
1081             __usecols  = (0, 1, 2, 3)
1082             def __replaceNoneN( s ):
1083                 if s.strip() == b'None': return numpy.NINF
1084                 else:                    return s
1085             def __replaceNoneP( s ):
1086                 if s.strip() == b'None': return numpy.PINF
1087                 else:                    return s
1088             __converters = {2: __replaceNoneN, 3: __replaceNoneP}
1089         elif "Name" in self._varsline and "Value" in self._varsline and ("Minimum" not in self._varsline or "Maximum" not in self._varsline):
1090             __ftype = "NamVal"
1091             __dtypes   = {'names'  : ('Name', 'Value'),
1092                           'formats': ('S128', 'g')}
1093             __converters = None
1094             __usecols  = (0, 1)
1095         elif len(HeaderNames)>0 and numpy.all([kw in self._varsline for kw in HeaderNames]):
1096             __ftype = "NamLotOfVals"
1097             __dtypes   = {'names'  : HeaderNames,
1098                           'formats': tuple(['S128',]+['g']*(len(HeaderNames)-1))}
1099             __usecols  = tuple(range(len(HeaderNames)))
1100             def __replaceNone( s ):
1101                 if s.strip() == b'None': return numpy.NAN
1102                 else:                    return s
1103             __converters = dict()
1104             for i in range(1,len(HeaderNames)):
1105                 __converters[i] = __replaceNone
1106         else:
1107             raise ValueError("Can not find names of columns for initial values. Wrong first line is:\n            \"%s\""%self._varsline)
1108         #
1109         if self._format == "text/plain":
1110             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters)
1111         elif self._format in ["text/csv", "text/tab-separated-values"]:
1112             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters, delimiter = self._delimiter)
1113         else:
1114             raise ValueError("Unkown file format \"%s\""%self._format)
1115         #
1116         __names, __thevalue, __bounds = [], [], []
1117         for sub in __content:
1118             if len(__usecols) == 4:
1119                 na, va, mi, ma = sub
1120                 if numpy.isneginf(mi): mi = None # Réattribue les variables None
1121                 elif numpy.isnan(mi):  mi = None # Réattribue les variables None
1122                 if numpy.isposinf(ma): ma = None # Réattribue les variables None
1123                 elif numpy.isnan(ma):  ma = None # Réattribue les variables None
1124             elif len(__usecols) == 2 and __ftype == "NamVal":
1125                 na, va = sub
1126                 mi, ma = None, None
1127             else:
1128                 nsub = list(sub)
1129                 na = sub[0]
1130                 for i, v in enumerate(nsub[1:]):
1131                     if numpy.isnan(v): nsub[i+1] = None
1132                 va = nsub[1:]
1133                 mi, ma = None, None
1134             na = na.decode()
1135             if (__varnames is None or na in __varnames) and (na not in __names):
1136                 # Ne stocke que la premiere occurence d'une variable
1137                 __names.append(na)
1138                 __thevalue.append(va)
1139                 __bounds.append((mi,ma))
1140         #
1141         __names      = tuple(__names)
1142         __thevalue = numpy.array(__thevalue)
1143         __bounds     = tuple(__bounds)
1144         #
1145         return (__names, __thevalue, __bounds)
1146
1147 # ==============================================================================
1148 class EficasGUI(object):
1149     """
1150     Lancement autonome de l'interface EFICAS/ADAO
1151     """
1152     def __init__(self, __addpath = None):
1153         # Chemin pour l'installation (ordre important)
1154         self.__msg = ""
1155         self.__path_settings_ok = False
1156         #----------------
1157         if "EFICAS_ROOT" in os.environ:
1158             __EFICAS_ROOT = os.environ["EFICAS_ROOT"]
1159             __path_ok = True
1160         elif "EFICAS_NOUVEAU_ROOT" in os.environ:
1161             __EFICAS_ROOT = os.environ["EFICAS_NOUVEAU_ROOT"]
1162             __path_ok = True
1163         else:
1164             self.__msg += "\nKeyError:\n"+\
1165                 "  the required environment variable EFICAS_ROOT is unknown.\n"+\
1166                 "  You have either to be in SALOME environment, or to set\n"+\
1167                 "  this variable in your environment to the right path \"<...>\"\n"+\
1168                 "  to find an installed EFICAS application. For example:\n"+\
1169                 "      EFICAS_ROOT=\"<...>\" command\n"
1170             __path_ok = False
1171         try:
1172             import adao
1173             __path_ok = True and __path_ok
1174         except ImportError:
1175             self.__msg += "\nImportError:\n"+\
1176                 "  the required ADAO library can not be found to be imported.\n"+\
1177                 "  You have either to be in ADAO environment, or to be in SALOME\n"+\
1178                 "  environment, or to set manually in your Python 3 environment the\n"+\
1179                 "  right path \"<...>\" to find an installed ADAO application. For\n"+\
1180                 "  example:\n"+\
1181                 "      PYTHONPATH=\"<...>:${PYTHONPATH}\" command\n"
1182             __path_ok = False
1183         try:
1184             import PyQt5
1185             __path_ok = True and __path_ok
1186         except ImportError:
1187             self.__msg += "\nImportError:\n"+\
1188                 "  the required PyQt5 library can not be found to be imported.\n"+\
1189                 "  You have either to have a raisonable up-to-date Python 3\n"+\
1190                 "  installation (less than 5 years), or to be in SALOME environment.\n"
1191             __path_ok = False
1192         #----------------
1193         if not __path_ok:
1194             self.__msg += "\nWarning:\n"+\
1195                 "  It seems you have some troubles with your installation.\n"+\
1196                 "  Be aware that some other errors may exist, that are not\n"+\
1197                 "  explained as above, like some incomplete or obsolete\n"+\
1198                 "  Python 3, or incomplete module installation.\n"+\
1199                 "  \n"+\
1200                 "  Please correct the above error(s) before launching the\n"+\
1201                 "  standalone EFICAS/ADAO interface.\n"
1202             logging.debug("Some of the ADAO/EFICAS/QT5 paths have not been found")
1203             self.__path_settings_ok = False
1204         else:
1205             logging.debug("All the ADAO/EFICAS/QT5 paths have been found")
1206             self.__path_settings_ok = True
1207         #----------------
1208         if self.__path_settings_ok:
1209             sys.path.insert(0,__EFICAS_ROOT)
1210             sys.path.insert(0,os.path.join(adao.adao_py_dir,"daEficas"))
1211             if __addpath is not None and os.path.exists(os.path.abspath(__addpath)):
1212                 sys.path.insert(0,os.path.abspath(__addpath))
1213             logging.debug("All the paths have been correctly set up")
1214         else:
1215             print(self.__msg)
1216             logging.debug("Errors in path settings have been found")
1217
1218     def gui(self):
1219         if self.__path_settings_ok:
1220             logging.debug("Launching standalone EFICAS/ADAO interface...")
1221             from daEficas import prefs
1222             from InterfaceQT4 import eficas_go
1223             eficas_go.lanceEficas(code=prefs.code)
1224         else:
1225             logging.debug("Can not launch standalone EFICAS/ADAO interface for path errors.")
1226
1227 # ==============================================================================
1228 if __name__ == "__main__":
1229     print('\n AUTODIAGNOSTIC\n')