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