]> SALOME platform Git repositories - modules/adao.git/blob - src/daComposant/daCore/Interfaces.py
Salome HOME
19a42d515e010ee38628ac7e59bdbc6b21e13667
[modules/adao.git] / src / daComposant / daCore / Interfaces.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2018 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 logging
32 import copy
33 import numpy
34 from daCore import Persistence
35 from daCore import PlatformInfo
36 from daCore import Templates
37
38 # ==============================================================================
39 class GenericCaseViewer(object):
40     """
41     Gestion des commandes de creation d'une vue de cas
42     """
43     def __init__(self, __name="", __objname="case", __content=None, __object=None):
44         "Initialisation et enregistrement de l'entete"
45         self._name         = str(__name)
46         self._objname      = str(__objname)
47         self._lineSerie    = []
48         self._switchoff    = False
49         self._numobservers = 2
50         self._content      = __content
51         self._object       = __object
52         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# """
53     def _append(self, *args):
54         "Transformation de commande individuelle en enregistrement"
55         raise NotImplementedError()
56     def _extract(self, *args):
57         "Transformation d'enregistrement en commande individuelle"
58         raise NotImplementedError()
59     def _finalize(self, __upa=None):
60         "Enregistrement du final"
61         if __upa is not None and len(__upa)>0:
62             self._lineSerie.append("%s.execute()"%(self._objname,))
63             self._lineSerie.append(__upa)
64     def _addLine(self, line=""):
65         "Ajoute un enregistrement individuel"
66         self._lineSerie.append(line)
67     def _get_objname(self):
68         return self._objname
69     def dump(self, __filename=None, __upa=None):
70         "Restitution normalisée des commandes"
71         self._finalize(__upa)
72         __text = "\n".join(self._lineSerie)
73         __text +="\n"
74         if __filename is not None:
75             __file = os.path.abspath(__filename)
76             __fid = open(__file,"w")
77             __fid.write(__text)
78             __fid.close()
79         return __text
80     def load(self, __filename=None, __content=None, __object=None):
81         "Chargement normalisé des commandes"
82         if __filename is not None and os.path.exists(__filename):
83             self._content = open(__filename, 'r').read()
84         elif __content is not None and type(__content) is str:
85             self._content = __content
86         elif __object is not None and type(__object) is dict:
87             self._object = copy.deepcopy(__object)
88         else:
89             pass # use "self._content" from initialization
90         __commands = self._extract(self._content, self._object)
91         return __commands
92
93 class _TUIViewer(GenericCaseViewer):
94     """
95     Etablissement des commandes d'un cas ADAO TUI (Cas<->TUI)
96     """
97     def __init__(self, __name="", __objname="case", __content=None, __object=None):
98         "Initialisation et enregistrement de l'entete"
99         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
100         self._addLine("# -*- coding: utf-8 -*-")
101         self._addLine("#\n# Python script using ADAO TUI\n#")
102         self._addLine("from numpy import array, matrix")
103         self._addLine("import adaoBuilder")
104         self._addLine("%s = adaoBuilder.New('%s')"%(self._objname, self._name))
105         if self._content is not None:
106             for command in self._content:
107                 self._append(*command)
108     def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
109         "Transformation d'une commande individuelle en un enregistrement"
110         if __command is not None and __keys is not None and __local is not None:
111             __text  = ""
112             if __pre is not None:
113                 __text += "%s = "%__pre
114             __text += "%s.%s( "%(self._objname,str(__command))
115             if "self" in __keys: __keys.remove("self")
116             if __command not in ("set","get") and "Concept" in __keys: __keys.remove("Concept")
117             for k in __keys:
118                 __v = __local[k]
119                 if __v is None: continue
120                 if   k == "Checked" and not __v: continue
121                 if   k == "Stored"  and not __v: continue
122                 if   k == "AvoidRC" and __v: continue
123                 if   k == "noDetails": continue
124                 if isinstance(__v,Persistence.Persistence): __v = __v.values()
125                 if callable(__v): __text = self._missing%__v.__name__+__text
126                 if isinstance(__v,dict):
127                     for val in __v.values():
128                         if callable(val): __text = self._missing%val.__name__+__text
129                 numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
130                 __text += "%s=%s, "%(k,repr(__v))
131                 numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
132             __text.rstrip(", ")
133             __text += ")"
134             self._addLine(__text)
135     def _extract(self, __multilines="", __object=None):
136         "Transformation un enregistrement en une commande individuelle"
137         __is_case = False
138         __commands = []
139         __multilines = __multilines.replace("\r\n","\n")
140         for line in __multilines.split("\n"):
141             if "adaoBuilder.New" in line and "=" in line:
142                 self._objname = line.split("=")[0].strip()
143                 __is_case = True
144                 logging.debug("TUI Extracting commands of '%s' object..."%(self._objname,))
145             if not __is_case:
146                 continue
147             else:
148                 if self._objname+".set" in line:
149                     __commands.append( line.replace(self._objname+".","",1) )
150                     logging.debug("TUI Extracted command: %s"%(__commands[-1],))
151         return __commands
152
153 class _COMViewer(GenericCaseViewer):
154     """
155     Etablissement des commandes d'un cas COMM (Eficas Native Format/Cas<-COM)
156     """
157     def __init__(self, __name="", __objname="case", __content=None, __object=None):
158         "Initialisation et enregistrement de l'entete"
159         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
160         self._observerIndex = 0
161         self._addLine("# -*- coding: utf-8 -*-")
162         self._addLine("#\n# Python script using ADAO COMM\n#")
163         self._addLine("from numpy import array, matrix")
164         self._addLine("#")
165         self._addLine("%s = {}"%__objname)
166         if self._content is not None:
167             for command in self._content:
168                 self._append(*command)
169     def _extract(self, __multilines=None, __object=None):
170         "Transformation un enregistrement en une commande individuelle"
171         if __multilines is not None:
172             __multilines = __multilines.replace("ASSIMILATION_STUDY","dict")
173             __multilines = __multilines.replace("CHECKING_STUDY",    "dict")
174             __multilines = __multilines.replace("_F(",               "dict(")
175             __multilines = __multilines.replace(",),);",             ",),)")
176         __fulllines = ""
177         for line in __multilines.split("\n"):
178             if len(line) < 1: continue
179             __fulllines += line + "\n"
180         __multilines = __fulllines
181         self._objname = "case"
182         self._objdata = None
183         exec("self._objdata = "+__multilines)
184         #
185         if self._objdata is None or not(type(self._objdata) is dict) or not('AlgorithmParameters' in self._objdata):
186             raise ValueError("Impossible to load given content as an ADAO COMM one (no dictionnary or no 'AlgorithmParameters' key found).")
187         # ----------------------------------------------------------------------
188         logging.debug("COMM Extracting commands of '%s' object..."%(self._objname,))
189         __commands = []
190         __UserPostAnalysis = ""
191         for k,r in self._objdata.items():
192             __command = k
193             logging.debug("COMM Extracted command: %s:%s"%(k, r))
194             if   __command == "StudyName" and len(str(r))>0:
195                 __commands.append( "set( Concept='Name', String='%s')"%(str(r),) )
196             elif   __command == "StudyRepertory":
197                 __commands.append( "set( Concept='Directory', String='%s')"%(str(r),) )
198             #
199             elif __command == "UserPostAnalysis" and type(r) is dict:
200                 if 'STRING' in r:
201                     __UserPostAnalysis = r['STRING']
202                 elif 'SCRIPT_FILE' in r and os.path.exists(r['SCRIPT_FILE']):
203                     __UserPostAnalysis = open(r['SCRIPT_FILE'],'r').read()
204                 elif 'Template' in r and 'ValueTemplate' in r:
205                     # AnalysisPrinter...
206                     __UserPostAnalysis = r['ValueTemplate']
207                 else:
208                     __UserPostAnalysis = ""
209                 __UserPostAnalysis = __UserPostAnalysis.replace("ADD",self._objname)
210             #
211             elif __command == "AlgorithmParameters" and type(r) is dict and 'Algorithm' in r:
212                 if 'data' in r and r['Parameters'] == 'Dict':
213                     __from = r['data']
214                     if 'STRING' in __from:
215                         __parameters = ", Parameters=%s"%(repr(eval(__from['STRING'])),)
216                     elif 'SCRIPT_FILE' in __from and os.path.exists(__from['SCRIPT_FILE']):
217                         __parameters = ", Script='%s'"%(__from['SCRIPT_FILE'],)
218                 else: # if 'Parameters' in r and r['Parameters'] == 'Defaults':
219                     __Dict = copy.deepcopy(r)
220                     __Dict.pop('Algorithm','')
221                     __Dict.pop('Parameters','')
222                     if 'SetSeed' in __Dict:__Dict['SetSeed'] = int(__Dict['SetSeed'])
223                     if 'BoxBounds' in __Dict and type(__Dict['BoxBounds']) is str:
224                         __Dict['BoxBounds'] = eval(__Dict['BoxBounds'])
225                     if len(__Dict) > 0:
226                         __parameters = ', Parameters=%s'%(repr(__Dict),)
227                     else:
228                         __parameters = ""
229                 __commands.append( "set( Concept='AlgorithmParameters', Algorithm='%s'%s )"%(r['Algorithm'],__parameters) )
230             #
231             elif __command == "Observers" and type(r) is dict and 'SELECTION' in r:
232                 if type(r['SELECTION']) is str:
233                     __selection = (r['SELECTION'],)
234                 else:
235                     __selection = tuple(r['SELECTION'])
236                 for sk in __selection:
237                     __idata = r['%s_data'%sk]
238                     if __idata['NodeType'] == 'Template' and 'Template' in __idata:
239                         __template = __idata['Template']
240                         if 'Info' in __idata:
241                             __info = ", Info='%s'"%(__idata['Info'],)
242                         else:
243                             __info = ""
244                         __commands.append( "set( Concept='Observer', Variable='%s', Template='%s'%s )"%(sk,__template,__info) )
245                     if __idata['NodeType'] == 'String' and 'Value' in __idata:
246                         __value =__idata['Value']
247                         __commands.append( "set( Concept='Observer', Variable='%s', String='%s' )"%(sk,__value) )
248             #
249             # Background, ObservationError, ObservationOperator...
250             elif type(r) is dict:
251                 __argumentsList = []
252                 if 'Stored' in r and bool(r['Stored']):
253                     __argumentsList.append(['Stored',True])
254                 if 'INPUT_TYPE' in r and 'data' in r:
255                     # Vector, Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, Function
256                     __itype = r['INPUT_TYPE']
257                     __idata = r['data']
258                     if 'FROM' in __idata:
259                         # String, Script, Template, ScriptWithOneFunction, ScriptWithFunctions
260                         __ifrom = __idata['FROM']
261                         __idata.pop('FROM','')
262                         if __ifrom == 'String' or __ifrom == 'Template':
263                             __argumentsList.append([__itype,__idata['STRING']])
264                         if __ifrom == 'Script':
265                             __argumentsList.append([__itype,True])
266                             __argumentsList.append(['Script',__idata['SCRIPT_FILE']])
267                         if __ifrom == 'ScriptWithOneFunction':
268                             __argumentsList.append(['OneFunction',True])
269                             __argumentsList.append(['Script',__idata.pop('SCRIPTWITHONEFUNCTION_FILE')])
270                             if len(__idata)>0:
271                                 __argumentsList.append(['Parameters',__idata])
272                         if __ifrom == 'ScriptWithFunctions':
273                             __argumentsList.append(['ThreeFunctions',True])
274                             __argumentsList.append(['Script',__idata.pop('SCRIPTWITHFUNCTIONS_FILE')])
275                             if len(__idata)>0:
276                                 __argumentsList.append(['Parameters',__idata])
277                 __arguments = ["%s = %s"%(k,repr(v)) for k,v in __argumentsList]
278                 __commands.append( "set( Concept='%s', %s )"%(__command, ", ".join(__arguments)))
279         #
280         # ----------------------------------------------------------------------
281         __commands.sort() # Pour commencer par 'AlgorithmParameters'
282         __commands.append(__UserPostAnalysis)
283         return __commands
284
285 class _SCDViewer(GenericCaseViewer):
286     """
287     Etablissement des commandes d'un cas SCD (Study Config Dictionary/Cas->SCD)
288     """
289     def __init__(self, __name="", __objname="case", __content=None, __object=None):
290         "Initialisation et enregistrement de l'entete"
291         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
292         self._addLine("# -*- coding: utf-8 -*-")
293         self._addLine("#\n# Input for ADAO converter to YACS\n#")
294         self._addLine("from numpy import array, matrix")
295         self._addLine("#")
296         self._addLine("study_config = {}")
297         self._addLine("study_config['StudyType'] = 'ASSIMILATION_STUDY'")
298         self._addLine("study_config['Name'] = '%s'"%self._name)
299         self._addLine("observers = {}")
300         self._addLine("study_config['Observers'] = observers")
301         self._addLine("#")
302         self._addLine("inputvariables_config = {}")
303         self._addLine("inputvariables_config['Order'] =['adao_default']")
304         self._addLine("inputvariables_config['adao_default'] = -1")
305         self._addLine("study_config['InputVariables'] = inputvariables_config")
306         self._addLine("#")
307         self._addLine("outputvariables_config = {}")
308         self._addLine("outputvariables_config['Order'] = ['adao_default']")
309         self._addLine("outputvariables_config['adao_default'] = -1")
310         self._addLine("study_config['OutputVariables'] = outputvariables_config")
311         if __content is not None:
312             for command in __content:
313                 self._append(*command)
314     def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
315         "Transformation d'une commande individuelle en un enregistrement"
316         if __command == "set": __command = __local["Concept"]
317         else:                  __command = __command.replace("set", "", 1)
318         #
319         __text  = None
320         if __command in (None, 'execute', 'executePythonScheme', 'executeYACSScheme', 'get', 'Name'):
321             return
322         elif __command in ['Debug', 'setDebug']:
323             __text  = "#\nstudy_config['Debug'] = '1'"
324         elif __command in ['NoDebug', 'setNoDebug']:
325             __text  = "#\nstudy_config['Debug'] = '0'"
326         elif __command in ['Observer', 'setObserver']:
327             __obs   = __local['Variable']
328             self._numobservers += 1
329             __text  = "#\n"
330             __text += "observers['%s'] = {}\n"%__obs
331             if __local['String'] is not None:
332                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
333                 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, __local['String'])
334             if __local['Script'] is not None:
335                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'Script')
336                 __text += "observers['%s']['Script'] = \"%s\"\n"%(__obs, __local['Script'])
337             if __local['Template'] is not None and __local['Template'] in Templates.ObserverTemplates:
338                 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
339                 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, Templates.ObserverTemplates[__local['Template']])
340             if __local['Info'] is not None:
341                 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __local['Info'])
342             else:
343                 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __obs)
344             __text += "observers['%s']['number'] = %s"%(__obs, self._numobservers)
345         elif __local is not None: # __keys is not None and
346             numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
347             __text  = "#\n"
348             __text += "%s_config = {}\n"%__command
349             __local.pop('self','')
350             __to_be_removed = []
351             for __k,__v in __local.items():
352                 if __v is None: __to_be_removed.append(__k)
353             for __k in __to_be_removed:
354                 __local.pop(__k)
355             for __k,__v in __local.items():
356                 if __k == "Concept": continue
357                 if __k in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix','OneFunction','ThreeFunctions'] and 'Script' in __local: continue
358                 if __k == 'Algorithm':
359                     __text += "study_config['Algorithm'] = %s\n"%(repr(__v))
360                 elif __k == 'Script':
361                     __k = 'Vector'
362                     __f = 'Script'
363                     __v = "'"+repr(__v)+"'"
364                     for __lk in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix']:
365                         if __lk in __local and __local[__lk]: __k = __lk
366                     if __command == "AlgorithmParameters": __k = "Dict"
367                     if 'OneFunction' in __local and __local['OneFunction']:
368                         __text += "%s_ScriptWithOneFunction = {}\n"%(__command,)
369                         __text += "%s_ScriptWithOneFunction['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
370                         __text += "%s_ScriptWithOneFunction['Script'] = {}\n"%(__command,)
371                         __text += "%s_ScriptWithOneFunction['Script']['Direct'] = %s\n"%(__command,__v)
372                         __text += "%s_ScriptWithOneFunction['Script']['Tangent'] = %s\n"%(__command,__v)
373                         __text += "%s_ScriptWithOneFunction['Script']['Adjoint'] = %s\n"%(__command,__v)
374                         __text += "%s_ScriptWithOneFunction['DifferentialIncrement'] = 1e-06\n"%(__command,)
375                         __text += "%s_ScriptWithOneFunction['CenteredFiniteDifference'] = 0\n"%(__command,)
376                         __k = 'Function'
377                         __f = 'ScriptWithOneFunction'
378                         __v = '%s_ScriptWithOneFunction'%(__command,)
379                     if 'ThreeFunctions' in __local and __local['ThreeFunctions']:
380                         __text += "%s_ScriptWithFunctions = {}\n"%(__command,)
381                         __text += "%s_ScriptWithFunctions['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
382                         __text += "%s_ScriptWithFunctions['Script'] = {}\n"%(__command,)
383                         __text += "%s_ScriptWithFunctions['Script']['Direct'] = %s\n"%(__command,__v)
384                         __text += "%s_ScriptWithFunctions['Script']['Tangent'] = %s\n"%(__command,__v)
385                         __text += "%s_ScriptWithFunctions['Script']['Adjoint'] = %s\n"%(__command,__v)
386                         __k = 'Function'
387                         __f = 'ScriptWithFunctions'
388                         __v = '%s_ScriptWithFunctions'%(__command,)
389                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
390                     __text += "%s_config['From'] = '%s'\n"%(__command,__f)
391                     __text += "%s_config['Data'] = %s\n"%(__command,__v)
392                     __text = __text.replace("''","'")
393                 elif __k in ('Stored', 'Checked'):
394                     if bool(__v):
395                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
396                 elif __k in ('AvoidRC', 'noDetails'):
397                     if not bool(__v):
398                         __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
399                 else:
400                     if __k == 'Parameters': __k = "Dict"
401                     if isinstance(__v,Persistence.Persistence): __v = __v.values()
402                     if callable(__v): __text = self._missing%__v.__name__+__text
403                     if isinstance(__v,dict):
404                         for val in __v.values():
405                             if callable(val): __text = self._missing%val.__name__+__text
406                     __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
407                     __text += "%s_config['From'] = '%s'\n"%(__command,'String')
408                     __text += "%s_config['Data'] = \"\"\"%s\"\"\"\n"%(__command,repr(__v))
409             __text += "study_config['%s'] = %s_config"%(__command,__command)
410             numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
411             if __switchoff:
412                 self._switchoff = True
413         if __text is not None: self._addLine(__text)
414         if not __switchoff:
415             self._switchoff = False
416     def _finalize(self, *__args):
417         self.__loadVariablesByScript()
418         self._addLine("#")
419         self._addLine("Analysis_config = {}")
420         self._addLine("Analysis_config['From'] = 'String'")
421         self._addLine("Analysis_config['Data'] = \"\"\"import numpy")
422         self._addLine("xa=numpy.ravel(ADD.get('Analysis')[-1])")
423         self._addLine("print 'Analysis:',xa\"\"\"")
424         self._addLine("study_config['UserPostAnalysis'] = Analysis_config")
425     def __loadVariablesByScript(self):
426         __ExecVariables = {} # Necessaire pour recuperer la variable
427         exec("\n".join(self._lineSerie), __ExecVariables)
428         study_config = __ExecVariables['study_config']
429         # Pour Python 3 : self.__hasAlgorithm = bool(study_config['Algorithm'])
430         if 'Algorithm' in study_config:
431             self.__hasAlgorithm = True
432         else:
433             self.__hasAlgorithm = False
434         if not self.__hasAlgorithm and \
435                 "AlgorithmParameters" in study_config and \
436                 isinstance(study_config['AlgorithmParameters'], dict) and \
437                 "From" in study_config['AlgorithmParameters'] and \
438                 "Data" in study_config['AlgorithmParameters'] and \
439                 study_config['AlgorithmParameters']['From'] == 'Script':
440             __asScript = study_config['AlgorithmParameters']['Data']
441             __var = ImportFromScript(__asScript).getvalue( "Algorithm" )
442             __text = "#\nstudy_config['Algorithm'] = '%s'"%(__var,)
443             self._addLine(__text)
444         if self.__hasAlgorithm and \
445                 "AlgorithmParameters" in study_config and \
446                 isinstance(study_config['AlgorithmParameters'], dict) and \
447                 "From" not in study_config['AlgorithmParameters'] and \
448                 "Data" not in study_config['AlgorithmParameters']:
449             __text  = "#\n"
450             __text += "AlgorithmParameters_config['Type'] = 'Dict'\n"
451             __text += "AlgorithmParameters_config['From'] = 'String'\n"
452             __text += "AlgorithmParameters_config['Data'] = '{}'\n"
453             self._addLine(__text)
454         del study_config
455
456 class _YACSViewer(GenericCaseViewer):
457     """
458     Etablissement des commandes d'un cas YACS (Cas->SCD->YACS)
459     """
460     def __init__(self, __name="", __objname="case", __content=None, __object=None):
461         "Initialisation et enregistrement de l'entete"
462         GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
463         self.__internalSCD = _SCDViewer(__name, __objname, __content, __object)
464         self._append       = self.__internalSCD._append
465     def dump(self, __filename=None, __upa=None):
466         "Restitution normalisée des commandes"
467         # -----
468         if __filename is None:
469             raise ValueError("A file name has to be given for YACS XML output.")
470         else:
471             __file    = os.path.abspath(__filename)
472             if os.path.isfile(__file) or os.path.islink(__file):
473                 os.remove(__file)
474         # -----
475         if not PlatformInfo.has_salome or \
476             not PlatformInfo.has_adao:
477             raise ImportError(
478                 "Unable to get SALOME or ADAO environnement variables for YACS conversion.\n"+\
479                 "Please load the right environnement before trying to use it.")
480         else:
481             from daYacsSchemaCreator.run import create_schema_from_content
482         # -----
483         self.__internalSCD._finalize(__upa)
484         __SCDdump = self.__internalSCD.dump()
485         create_schema_from_content(__SCDdump, __file)
486         # -----
487         if not os.path.exists(__file):
488             __msg  = "An error occured during the ADAO YACS Schema build for\n"
489             __msg += "the target output file:\n"
490             __msg += "  %s\n"%__file
491             __msg += "See errors details in your launching terminal log.\n"
492             raise ValueError(__msg)
493         # -----
494         __fid = open(__file,"r")
495         __text = __fid.read()
496         __fid.close()
497         return __text
498
499 # ==============================================================================
500 class ImportFromScript(object):
501     """
502     Obtention d'une variable nommee depuis un fichier script importé
503     """
504     __slots__ = ("__basename", "__filenspace", "__filestring")
505     def __init__(self, __filename=None):
506         "Verifie l'existence et importe le script"
507         if __filename is None:
508             raise ValueError("The name of the file, containing the variable to be read, has to be specified.")
509         if not os.path.isfile(__filename):
510             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))
511         if os.path.dirname(__filename) != '':
512             sys.path.insert(0, os.path.dirname(__filename))
513             __basename = os.path.basename(__filename).rstrip(".py")
514         else:
515             __basename = __filename.rstrip(".py")
516         self.__basename = __basename
517         self.__filenspace = __import__(__basename, globals(), locals(), [])
518         self.__filestring = open(__filename,'r').read()
519     def getvalue(self, __varname=None, __synonym=None ):
520         "Renvoie la variable demandee par son nom ou son synonyme"
521         if __varname is None:
522             raise ValueError("The name of the variable to be read has to be specified. Please check the content of the file and the syntax.")
523         if not hasattr(self.__filenspace, __varname):
524             if __synonym is None:
525                 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))
526             elif not hasattr(self.__filenspace, __synonym):
527                 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))
528             else:
529                 return getattr(self.__filenspace, __synonym)
530         else:
531             return getattr(self.__filenspace, __varname)
532     def getstring(self):
533         "Renvoie le script complet"
534         return self.__filestring
535
536 # ==============================================================================
537 class ImportFromFile(object):
538     """
539     Obtention de variables disrétisées en 1D, définies par une ou des variables
540     nommées, et sous la forme d'une série de points éventuellement indexés. La
541     lecture d'un fichier au format spécifié (ou intuité) permet de charger ces
542     fonctions depuis :
543         - des fichiers textes en colonnes de type TXT, CSV, TSV...
544         - des fichiers de données binaires NPY, NPZ...
545     La lecture du fichier complet ne se fait que si nécessaire, pour assurer la
546     performance tout en disposant de l'interprétation du contenu. Les fichiers
547     textes doivent présenter en première ligne (hors commentaire ou ligne vide)
548     les noms des variables de colonnes. Les commentaires commencent par un "#".
549     """
550     __slots__ = (
551         "_filename", "_varsline", "_format", "_delimiter", "_skiprows",
552         "__colnames", "__colindex", "__filestring", "__header")
553     def __enter__(self): return self
554     def __exit__(self, exc_type, exc_val, exc_tb): return False
555     #
556     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess"):
557         """
558         Verifie l'existence et les informations de définition du fichier. Les
559         noms de colonnes ou de variables sont ignorées si le format ne permet
560         pas de les indiquer.
561         Arguments :
562             - Filename : nom du fichier
563             - ColNames : noms de la ou des colonnes/variables à lire
564             - ColIndex : nom unique de la colonne/variable servant d'index
565             - Format : format du fichier et/ou des données inclues
566         """
567         if Filename is None:
568             raise ValueError("The name of the file, containing the variables to be read, has to be specified.")
569         if not os.path.isfile(Filename):
570             raise ValueError("The file, containing the variables to be read, doesn't seem to exist. Please check the file. The given file name is:\n  \"%s\""%str(Filename))
571         self._filename = os.path.abspath(Filename)
572         #
573         self.__header, self._varsline, self._skiprows = self.__getentete(self._filename)
574         #
575         self._delimiter = None
576         self.__filestring = "".join(self.__header)
577         if Format.upper() == "GUESS":
578             if self._filename.split(".")[-1].lower() == "npy":
579                 self._format = "NPY"
580             elif self._filename.split(".")[-1].lower() == "npz":
581                 self._format = "NPZ"
582             elif self.__filestring.count(",") > 1  and self._filename.split(".")[-1].lower() == "csv":
583                 self._format = "CSV"
584                 self._delimiter = ","
585             elif self.__filestring.count(";") > 1  and self._filename.split(".")[-1].lower() == "csv":
586                 self._format = "CSV"
587                 self._delimiter = ";"
588             elif self.__filestring.count("\t") > 1 and self._filename.split(".")[-1].lower() == "tsv":
589                 self._format = "TSV"
590                 self._delimiter = "\t"
591             elif self.__filestring.count(" ") > 1  and self._filename.split(".")[-1].lower() == "txt":
592                 self._format = "TXT"
593             else:
594                 raise ValueError("Can not guess the file format, please specify the good one")
595         elif Format.upper() == "CSV" and self._delimiter is None:
596             if self.__filestring.count(",") > 1 and self._filename.split(".")[-1].lower() == "csv":
597                 self._format    = "CSV"
598                 self._delimiter = ","
599             elif self.__filestring.count(";") > 1 and self._filename.split(".")[-1].lower() == "csv":
600                 self._format    = "CSV"
601                 self._delimiter = ";"
602         elif Format.upper() == "TSV" and self._delimiter is None:
603             self._format    = "TSV"
604             self._delimiter = "\t"
605         else:
606             self._format     = str(Format).upper()
607         #
608         if ColNames is not None: self.__colnames = tuple(ColNames)
609         else:                    self.__colnames = None
610         #
611         if ColIndex is not None: self.__colindex = str(ColIndex)
612         else:                    self.__colindex = None
613
614     def __getentete(self, __filename, __nblines = 3):
615         "Lit l'entête du fichier pour trouver la définition des variables"
616         __header, __varsline, __skiprows = [], "", 1
617         if __filename.split(".")[-1].lower() in ("npy", "npz"):
618             pass
619         else:
620             with open(__filename,'r') as fid:
621                 __line = fid.readline().strip()
622                 while "#" in __line or len(__line) < 1:
623                     __header.append(__line)
624                     __skiprows += 1
625                     __line = fid.readline().strip()
626                 __varsline = __line # Première ligne non commentée non vide
627                 for i in range(max(0,__nblines)):
628                     __header.append(fid.readline())
629         return (__header, __varsline, __skiprows)
630
631     def __getindices(self, __colnames, __colindex, __delimiter=None ):
632         "Indices de colonnes correspondants à l'index et aux variables"
633         if __delimiter is None:
634             __varserie = self._varsline.strip('#').strip().split()
635         else:
636             __varserie = self._varsline.strip('#').strip().split(str(__delimiter))
637         #
638         if __colnames is not None:
639             __usecols = []
640             __colnames = tuple(__colnames)
641             for v in __colnames:
642                 for i, n in enumerate(__varserie):
643                     if v == n: __usecols.append(i)
644             __usecols = tuple(__usecols)
645             if len(__usecols) == 0: __usecols = None
646         else:
647             __usecols = None
648         #
649         if __colindex is not None:
650             __useindex = None
651             __colindex = str(__colindex)
652             for i, n in enumerate(__varserie):
653                 if __colindex == n: __useindex = i
654         else:
655             __useindex = None
656         #
657         return (__usecols, __useindex)
658
659     def getvalue(self, ColNames=None, ColIndex=None ):
660         "Renvoie la ou les variables demandees par la liste de leurs noms"
661         # Uniquement si mise à jour
662         if ColNames is not None: self.__colnames = tuple(ColNames)
663         if ColIndex is not None: self.__colindex = str(ColIndex)
664         #
665         __index = None
666         if self._format == "NPY":
667             __columns = numpy.load(self._filename)
668         elif self._format == "NPZ":
669             __columns = None
670             with numpy.load(self._filename) as __allcolumns:
671                 if self.__colnames is None:
672                     self.__colnames = __allcolumns.files
673                 for nom in self.__colnames:
674                     if nom in __allcolumns.files:
675                         if __columns is not None:
676                             # Attention : toutes les variables doivent avoir la même taille
677                             __columns = numpy.vstack((__columns, numpy.reshape(__allcolumns[nom], (1,-1))))
678                         else:
679                             # Première colonne
680                             __columns = numpy.reshape(__allcolumns[nom], (1,-1))
681                 if self.__colindex is not None and self.__colindex in __allcolumns.files:
682                     __index = numpy.reshape(__allcolumns[self.__colindex], (1,-1))
683         elif self._format == "TXT":
684             __usecols, __useindex = self.__getindices(self.__colnames, self.__colindex)
685             __columns = numpy.loadtxt(self._filename, usecols = __usecols, skiprows=self._skiprows)
686             if __useindex is not None:
687                 __index = numpy.loadtxt(self._filename, usecols = __useindex, skiprows=self._skiprows)
688         #
689         elif self._format == "CSV":
690             __usecols, __useindex = self.__getindices(self.__colnames, self.__colindex, self._delimiter)
691             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
692             if __useindex is not None:
693                 __index = numpy.loadtxt(self._filename, usecols = __useindex, delimiter = self._delimiter, skiprows=self._skiprows)
694         #
695         elif self._format == "TSV":
696             __usecols, __useindex = self.__getindices(self.__colnames, self.__colindex, self._delimiter)
697             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
698             if __useindex is not None:
699                 __index = numpy.loadtxt(self._filename, usecols = __useindex, delimiter = self._delimiter, skiprows=self._skiprows)
700         else:
701             raise ValueError("Unkown file format %s"%self._format)
702         #
703         return (self.__colnames, __columns, self.__colindex, __index)
704
705     def getstring(self):
706         "Renvoie le fichier complet"
707         with open(self._filename,'r') as fid:
708             return fid.read()
709
710 # ==============================================================================
711 class ImportScalarLinesFromFile(ImportFromFile):
712     """
713     Importation de fichier contenant des variables scalaires nommées. Le
714     fichier comporte soit 2, soit 4 colonnes, obligatoirement nommées "Name",
715     "Value", "Minimum", "Maximum" si les noms sont précisés. Sur chaque ligne
716     est indiqué le nom, la valeur, et éventuelement deux bornes min et max (ou
717     None si nécessaire pour une borne).
718
719     Seule la méthode "getvalue" est changée.
720     """
721     def __enter__(self): return self
722     def __exit__(self, exc_type, exc_val, exc_tb): return False
723     #
724     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess"):
725         ImportFromFile.__init__(self, Filename, ColNames, ColIndex, Format)
726         if self._format not in ["TXT", "CSV", "TSV"]:
727             raise ValueError("Unkown file format \"%s\""%self._format)
728     #
729     def getvalue(self, VarNames = None, HeaderNames=()):
730         "Renvoie la ou les variables demandees par la liste de leurs noms"
731         if VarNames is not None: __varnames = tuple(VarNames)
732         else:                    __varnames = None
733         #
734         if "Name" in self._varsline and "Value" in self._varsline and "Minimum" in self._varsline and "Maximum" in self._varsline:
735             __ftype = "NamValMinMax"
736             __dtypes   = {'names'  : ('Name', 'Value', 'Minimum', 'Maximum'),
737                           'formats': ('S128', 'g', 'g', 'g')}
738             __usecols  = (0, 1, 2, 3)
739             def __replaceNoneN( s ):
740                 if s.strip() == b'None': return numpy.NINF
741                 else:                    return s
742             def __replaceNoneP( s ):
743                 if s.strip() == b'None': return numpy.PINF
744                 else:                    return s
745             __converters = {2: __replaceNoneN, 3: __replaceNoneP}
746         elif "Name" in self._varsline and "Value" in self._varsline and ("Minimum" not in self._varsline or "Maximum" not in self._varsline):
747             __ftype = "NamVal"
748             __dtypes   = {'names'  : ('Name', 'Value'),
749                           'formats': ('S128', 'g')}
750             __converters = None
751             __usecols  = (0, 1)
752         elif len(HeaderNames)>0 and numpy.all([kw in self._varsline for kw in HeaderNames]):
753             __ftype = "NamLotOfVals"
754             __dtypes   = {'names'  : HeaderNames,
755                           'formats': tuple(['S128',]+['g']*(len(HeaderNames)-1))}
756             __usecols  = tuple(range(len(HeaderNames)))
757             def __replaceNone( s ):
758                 if s.strip() == b'None': return numpy.NAN
759                 else:                    return s
760             __converters = dict()
761             for i in range(1,len(HeaderNames)):
762                 __converters[i] = __replaceNone
763         else:
764             raise ValueError("Can not find names of columns for initial values. Wrong first line is:\n            \"%s\""%__firstline)
765         #
766         if self._format == "TXT":
767             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters)
768         elif self._format in ["CSV", "TSV"]:
769             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters, delimiter = self._delimiter)
770         else:
771             raise ValueError("Unkown file format \"%s\""%self._format)
772         #
773         __names, __background, __bounds = [], [], []
774         for sub in __content:
775             if len(__usecols) == 4:
776                 na, va, mi, ma = sub
777                 if numpy.isneginf(mi): mi = None # Réattribue les variables None
778                 elif numpy.isnan(mi):  mi = None # Réattribue les variables None
779                 if numpy.isposinf(ma): ma = None # Réattribue les variables None
780                 elif numpy.isnan(ma):  ma = None # Réattribue les variables None
781             elif len(__usecols) == 2 and __ftype == "NamVal":
782                 na, va = sub
783                 mi, ma = None, None
784             else:
785                 nsub = list(sub)
786                 na = sub[0]
787                 for i, v in enumerate(nsub[1:]):
788                     if numpy.isnan(v): nsub[i+1] = None
789                 va = nsub[1:]
790                 mi, ma = None, None
791             na = na.decode()
792             if (__varnames is None or na in __varnames) and (na not in __names):
793                 # Ne stocke que la premiere occurence d'une variable
794                 __names.append(na)
795                 __background.append(va)
796                 __bounds.append((mi,ma))
797         #
798         __names      = tuple(__names)
799         __background = numpy.array(__background)
800         __bounds     = tuple(__bounds)
801         #
802         return (__names, __background, __bounds)
803
804 # ==============================================================================
805 if __name__ == "__main__":
806     print('\n AUTODIAGNOSTIC \n')