Salome HOME
969686ae5fdf69d2482afba6bc620288bff08390
[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", "__allowvoid")
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", AllowVoidNameList=True):
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             - AllowVoidNameList : permet, si la liste de noms est vide, de
567               prendre par défaut toutes les colonnes
568         """
569         if Filename is None:
570             raise ValueError("The name of the file, containing the variables to be read, has to be specified.")
571         if not os.path.isfile(Filename):
572             raise ValueError("The file, containing the variables to be read, doesn't seem to exist. The given file name is:\n  \"%s\""%str(Filename))
573         self._filename = os.path.abspath(Filename)
574         #
575         self.__header, self._varsline, self._skiprows = self.__getentete(self._filename)
576         #
577         self._delimiter = None
578         self.__filestring = "".join(self.__header)
579         if Format.upper() == "GUESS":
580             if self._filename.split(".")[-1].lower() == "npy":
581                 self._format = "NPY"
582             elif self._filename.split(".")[-1].lower() == "npz":
583                 self._format = "NPZ"
584             elif self.__filestring.count(",") > 1  and self._filename.split(".")[-1].lower() == "csv":
585                 self._format = "CSV"
586                 self._delimiter = ","
587             elif self.__filestring.count(";") > 1  and self._filename.split(".")[-1].lower() == "csv":
588                 self._format = "CSV"
589                 self._delimiter = ";"
590             elif self.__filestring.count("\t") > 1 and self._filename.split(".")[-1].lower() == "tsv":
591                 self._format = "TSV"
592                 self._delimiter = "\t"
593             elif self.__filestring.count(" ") > 1  and self._filename.split(".")[-1].lower() == "txt":
594                 self._format = "TXT"
595             else:
596                 raise ValueError("Can not guess the file format, please specify the good one")
597         elif Format.upper() == "CSV" and self._delimiter is None:
598             if self.__filestring.count(",") > 1 and self._filename.split(".")[-1].lower() == "csv":
599                 self._format    = "CSV"
600                 self._delimiter = ","
601             elif self.__filestring.count(";") > 1 and self._filename.split(".")[-1].lower() == "csv":
602                 self._format    = "CSV"
603                 self._delimiter = ";"
604         elif Format.upper() == "TSV" and self._delimiter is None:
605             self._format    = "TSV"
606             self._delimiter = "\t"
607         else:
608             self._format     = str(Format).upper()
609         #
610         if ColNames is not None: self.__colnames = tuple(ColNames)
611         else:                    self.__colnames = None
612         #
613         if ColIndex is not None: self.__colindex = str(ColIndex)
614         else:                    self.__colindex = None
615         #
616         self.__allowvoid = bool(AllowVoidNameList)
617
618     def __getentete(self, __filename, __nblines = 3):
619         "Lit l'entête du fichier pour trouver la définition des variables"
620         __header, __varsline, __skiprows = [], "", 1
621         if __filename.split(".")[-1].lower() in ("npy", "npz"):
622             pass
623         else:
624             with open(__filename,'r') as fid:
625                 __line = fid.readline().strip()
626                 while "#" in __line or len(__line) < 1:
627                     __header.append(__line)
628                     __skiprows += 1
629                     __line = fid.readline().strip()
630                 __varsline = __line # Première ligne non commentée non vide
631                 for i in range(max(0,__nblines)):
632                     __header.append(fid.readline())
633         return (__header, __varsline, __skiprows)
634
635     def __getindices(self, __colnames, __colindex, __delimiter=None ):
636         "Indices de colonnes correspondants à l'index et aux variables"
637         if __delimiter is None:
638             __varserie = self._varsline.strip('#').strip().split()
639         else:
640             __varserie = self._varsline.strip('#').strip().split(str(__delimiter))
641         #
642         if __colnames is not None:
643             __usecols = []
644             __colnames = tuple(__colnames)
645             for v in __colnames:
646                 for i, n in enumerate(__varserie):
647                     if v == n: __usecols.append(i)
648             __usecols = tuple(__usecols)
649             if len(__usecols) == 0:
650                 if self.__allowvoid:
651                     __usecols = None
652                 else:
653                     raise ValueError("Can not found any column corresponding to the required names %s"%(__colnames,))
654         else:
655             __usecols = None
656         #
657         if __colindex is not None:
658             __useindex = None
659             __colindex = str(__colindex)
660             for i, n in enumerate(__varserie):
661                 if __colindex == n: __useindex = i
662         else:
663             __useindex = None
664         #
665         return (__usecols, __useindex)
666
667     def getvalue(self, ColNames=None, ColIndex=None ):
668         "Renvoie la ou les variables demandees par la liste de leurs noms"
669         # Uniquement si mise à jour
670         if ColNames is not None: self.__colnames = tuple(ColNames)
671         if ColIndex is not None: self.__colindex = str(ColIndex)
672         #
673         __index = None
674         if self._format == "NPY":
675             __columns = numpy.load(self._filename)
676         elif self._format == "NPZ":
677             __columns = None
678             with numpy.load(self._filename) as __allcolumns:
679                 if self.__colnames is None:
680                     self.__colnames = __allcolumns.files
681                 for nom in self.__colnames:
682                     if nom in __allcolumns.files:
683                         if __columns is not None:
684                             # Attention : toutes les variables doivent avoir la même taille
685                             __columns = numpy.vstack((__columns, numpy.reshape(__allcolumns[nom], (1,-1))))
686                         else:
687                             # Première colonne
688                             __columns = numpy.reshape(__allcolumns[nom], (1,-1))
689                 if self.__colindex is not None and self.__colindex in __allcolumns.files:
690                     __index = numpy.array(numpy.reshape(__allcolumns[self.__colindex], (1,-1)), dtype=bytes)
691         elif self._format == "TXT":
692             __usecols, __useindex = self.__getindices(self.__colnames, self.__colindex)
693             __columns = numpy.loadtxt(self._filename, usecols = __usecols, skiprows=self._skiprows)
694             if __useindex is not None:
695                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), skiprows=self._skiprows)
696         #
697         elif self._format == "CSV":
698             __usecols, __useindex = self.__getindices(self.__colnames, self.__colindex, self._delimiter)
699             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
700             if __useindex is not None:
701                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
702         #
703         elif self._format == "TSV":
704             __usecols, __useindex = self.__getindices(self.__colnames, self.__colindex, self._delimiter)
705             __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
706             if __useindex is not None:
707                 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
708         else:
709             raise ValueError("Unkown file format %s"%self._format)
710         #
711         def toString(value):
712             try:
713                 return value.decode()
714             except ValueError:
715                 return value
716         if __index is not None:
717             __index = tuple([toString(v) for v in __index])
718         #
719         return (self.__colnames, __columns, self.__colindex, __index)
720
721     def getstring(self):
722         "Renvoie le fichier complet"
723         with open(self._filename,'r') as fid:
724             return fid.read()
725
726 # ==============================================================================
727 class ImportScalarLinesFromFile(ImportFromFile):
728     """
729     Importation de fichier contenant des variables scalaires nommées. Le
730     fichier comporte soit 2, soit 4 colonnes, obligatoirement nommées "Name",
731     "Value", "Minimum", "Maximum" si les noms sont précisés. Sur chaque ligne
732     est indiqué le nom, la valeur, et éventuelement deux bornes min et max (ou
733     None si nécessaire pour une borne).
734
735     Seule la méthode "getvalue" est changée.
736     """
737     def __enter__(self): return self
738     def __exit__(self, exc_type, exc_val, exc_tb): return False
739     #
740     def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess"):
741         ImportFromFile.__init__(self, Filename, ColNames, ColIndex, Format)
742         if self._format not in ["TXT", "CSV", "TSV"]:
743             raise ValueError("Unkown file format \"%s\""%self._format)
744     #
745     def getvalue(self, VarNames = None, HeaderNames=()):
746         "Renvoie la ou les variables demandees par la liste de leurs noms"
747         if VarNames is not None: __varnames = tuple(VarNames)
748         else:                    __varnames = None
749         #
750         if "Name" in self._varsline and "Value" in self._varsline and "Minimum" in self._varsline and "Maximum" in self._varsline:
751             __ftype = "NamValMinMax"
752             __dtypes   = {'names'  : ('Name', 'Value', 'Minimum', 'Maximum'),
753                           'formats': ('S128', 'g', 'g', 'g')}
754             __usecols  = (0, 1, 2, 3)
755             def __replaceNoneN( s ):
756                 if s.strip() == b'None': return numpy.NINF
757                 else:                    return s
758             def __replaceNoneP( s ):
759                 if s.strip() == b'None': return numpy.PINF
760                 else:                    return s
761             __converters = {2: __replaceNoneN, 3: __replaceNoneP}
762         elif "Name" in self._varsline and "Value" in self._varsline and ("Minimum" not in self._varsline or "Maximum" not in self._varsline):
763             __ftype = "NamVal"
764             __dtypes   = {'names'  : ('Name', 'Value'),
765                           'formats': ('S128', 'g')}
766             __converters = None
767             __usecols  = (0, 1)
768         elif len(HeaderNames)>0 and numpy.all([kw in self._varsline for kw in HeaderNames]):
769             __ftype = "NamLotOfVals"
770             __dtypes   = {'names'  : HeaderNames,
771                           'formats': tuple(['S128',]+['g']*(len(HeaderNames)-1))}
772             __usecols  = tuple(range(len(HeaderNames)))
773             def __replaceNone( s ):
774                 if s.strip() == b'None': return numpy.NAN
775                 else:                    return s
776             __converters = dict()
777             for i in range(1,len(HeaderNames)):
778                 __converters[i] = __replaceNone
779         else:
780             raise ValueError("Can not find names of columns for initial values. Wrong first line is:\n            \"%s\""%__firstline)
781         #
782         if self._format == "TXT":
783             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters)
784         elif self._format in ["CSV", "TSV"]:
785             __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters, delimiter = self._delimiter)
786         else:
787             raise ValueError("Unkown file format \"%s\""%self._format)
788         #
789         __names, __background, __bounds = [], [], []
790         for sub in __content:
791             if len(__usecols) == 4:
792                 na, va, mi, ma = sub
793                 if numpy.isneginf(mi): mi = None # Réattribue les variables None
794                 elif numpy.isnan(mi):  mi = None # Réattribue les variables None
795                 if numpy.isposinf(ma): ma = None # Réattribue les variables None
796                 elif numpy.isnan(ma):  ma = None # Réattribue les variables None
797             elif len(__usecols) == 2 and __ftype == "NamVal":
798                 na, va = sub
799                 mi, ma = None, None
800             else:
801                 nsub = list(sub)
802                 na = sub[0]
803                 for i, v in enumerate(nsub[1:]):
804                     if numpy.isnan(v): nsub[i+1] = None
805                 va = nsub[1:]
806                 mi, ma = None, None
807             na = na.decode()
808             if (__varnames is None or na in __varnames) and (na not in __names):
809                 # Ne stocke que la premiere occurence d'une variable
810                 __names.append(na)
811                 __background.append(va)
812                 __bounds.append((mi,ma))
813         #
814         __names      = tuple(__names)
815         __background = numpy.array(__background)
816         __bounds     = tuple(__bounds)
817         #
818         return (__names, __background, __bounds)
819
820 # ==============================================================================
821 if __name__ == "__main__":
822     print('\n AUTODIAGNOSTIC \n')