1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2020 EDF R&D
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.
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.
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
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
24 Définit les outils d'interfaces normalisées de cas.
26 __author__ = "Jean-Philippe ARGAUD"
35 from daCore import Persistence
36 from daCore import PlatformInfo
37 from daCore import Templates
39 # ==============================================================================
40 class GenericCaseViewer(object):
42 Gestion des commandes de création d'une vue de cas
44 def __init__(self, __name="", __objname="case", __content=None, __object=None):
45 "Initialisation et enregistrement de l'entete"
46 self._name = str(__name)
47 self._objname = str(__objname)
49 self._switchoff = False
50 self._numobservers = 2
51 self._content = __content
52 self._object = __object
53 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# """
54 def _append(self, *args):
55 "Transformation d'une commande individuelle en un enregistrement"
56 raise NotImplementedError()
57 def _extract(self, *args):
58 "Transformation d'enregistrement(s) en commande(s) individuelle(s)"
59 raise NotImplementedError()
60 def _finalize(self, __upa=None):
61 "Enregistrement du final"
62 __hasNotExecute = True
63 for l in self._lineSerie:
64 if "%s.execute"%(self._objname,) in l: __hasNotExecute = False
66 self._lineSerie.append("%s.execute()"%(self._objname,))
67 if __upa is not None and len(__upa)>0:
68 __upa = __upa.replace("ADD.",str(self._objname)+".")
69 self._lineSerie.append(__upa)
70 def _addLine(self, line=""):
71 "Ajoute un enregistrement individuel"
72 self._lineSerie.append(line)
73 def _get_objname(self):
75 def dump(self, __filename=None, __upa=None):
76 "Restitution normalisée des commandes"
78 __text = "\n".join(self._lineSerie)
80 if __filename is not None:
81 __file = os.path.abspath(__filename)
82 __fid = open(__file,"w")
86 def load(self, __filename=None, __content=None, __object=None):
87 "Chargement normalisé des commandes"
88 if __filename is not None and os.path.exists(__filename):
89 self._content = open(__filename, 'r').read()
90 elif __content is not None and type(__content) is str:
91 self._content = __content
92 elif __object is not None and type(__object) is dict:
93 self._object = copy.deepcopy(__object)
95 pass # use "self._content" from initialization
96 __commands = self._extract(self._content, self._object)
99 class _TUIViewer(GenericCaseViewer):
101 Établissement des commandes d'un cas ADAO TUI (Cas<->TUI)
103 def __init__(self, __name="", __objname="case", __content=None, __object=None):
104 "Initialisation et enregistrement de l'entete"
105 GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
106 self._addLine("# -*- coding: utf-8 -*-")
107 self._addLine("#\n# Python script using ADAO TUI\n#")
108 self._addLine("from numpy import array, matrix")
109 self._addLine("from adao import adaoBuilder")
110 self._addLine("%s = adaoBuilder.New('%s')"%(self._objname, self._name))
111 if self._content is not None:
112 for command in self._content:
113 self._append(*command)
114 def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
115 "Transformation d'une commande individuelle en un enregistrement"
116 if __command is not None and __keys is not None and __local is not None:
117 if "Concept" in __keys:
118 logging.debug("TUI Order processed: %s"%(__local["Concept"],))
120 if __pre is not None:
121 __text += "%s = "%__pre
122 __text += "%s.%s( "%(self._objname,str(__command))
123 if "self" in __keys: __keys.remove("self")
124 if __command not in ("set","get") and "Concept" in __keys: __keys.remove("Concept")
126 if k not in __local: continue
128 if __v is None: continue
129 if k == "Checked" and not __v: continue
130 if k == "Stored" and not __v: continue
131 if k == "ColMajor" and not __v: continue
132 if k == "InputFunctionAsMulti" and not __v: continue
133 if k == "nextStep" and not __v: continue
134 if k == "AvoidRC" and __v: continue
135 if k == "noDetails": continue
136 if isinstance(__v,Persistence.Persistence): __v = __v.values()
137 if callable(__v): __text = self._missing%__v.__name__+__text
138 if isinstance(__v,dict):
139 for val in __v.values():
140 if callable(val): __text = self._missing%val.__name__+__text
141 numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
142 __text += "%s=%s, "%(k,repr(__v))
143 numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
144 __text = __text.rstrip(", ")
146 self._addLine(__text)
147 def _extract(self, __multilines="", __object=None):
148 "Transformation d'enregistrement(s) en commande(s) individuelle(s)"
151 __multilines = __multilines.replace("\r\n","\n")
152 for line in __multilines.split("\n"):
153 if "adaoBuilder.New" in line and "=" in line:
154 self._objname = line.split("=")[0].strip()
156 logging.debug("TUI Extracting commands of '%s' object..."%(self._objname,))
160 if self._objname+".set" in line:
161 __commands.append( line.replace(self._objname+".","",1) )
162 logging.debug("TUI Extracted command: %s"%(__commands[-1],))
165 class _COMViewer(GenericCaseViewer):
167 Établissement des commandes d'un cas COMM (Eficas Native Format/Cas<-COM)
169 def __init__(self, __name="", __objname="case", __content=None, __object=None):
170 "Initialisation et enregistrement de l'entete"
171 GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
172 self._observerIndex = 0
173 self._addLine("# -*- coding: utf-8 -*-")
174 self._addLine("#\n# Python script using ADAO COMM\n#")
175 self._addLine("from numpy import array, matrix")
177 self._addLine("%s = {}"%__objname)
178 if self._content is not None:
179 for command in self._content:
180 self._append(*command)
181 def _extract(self, __multilines=None, __object=None):
182 "Transformation d'enregistrement(s) en commande(s) individuelle(s)"
183 __suppparameters = {}
184 if __multilines is not None:
185 if "ASSIMILATION_STUDY" in __multilines:
186 __suppparameters.update({'StudyType':"ASSIMILATION_STUDY"})
187 __multilines = __multilines.replace("ASSIMILATION_STUDY","dict")
188 elif "CHECKING_STUDY" in __multilines:
189 __suppparameters.update({'StudyType':"CHECKING_STUDY"})
190 __multilines = __multilines.replace("CHECKING_STUDY", "dict")
192 __multilines = __multilines.replace("ASSIMILATION_STUDY","dict")
194 __multilines = __multilines.replace("_F(", "dict(")
195 __multilines = __multilines.replace(",),);", ",),)")
197 for line in __multilines.split("\n"):
198 if len(line) < 1: continue
199 __fulllines += line + "\n"
200 __multilines = __fulllines
201 self._objname = "case"
203 exec("self._objdata = "+__multilines)
205 if self._objdata is None or not(type(self._objdata) is dict) or not('AlgorithmParameters' in self._objdata):
206 raise ValueError("Impossible to load given content as an ADAO COMM one (no dictionnary or no 'AlgorithmParameters' key found).")
207 # ----------------------------------------------------------------------
208 logging.debug("COMM Extracting commands of '%s' object..."%(self._objname,))
210 __UserPostAnalysis = ""
211 for k,r in self._objdata.items():
213 logging.debug("COMM Extracted command: %s:%s"%(k, r))
214 if __command == "StudyName" and len(str(r))>0:
215 __commands.append( "set( Concept='Name', String='%s')"%(str(r),) )
216 elif __command == "StudyRepertory":
217 __commands.append( "set( Concept='Directory', String='%s')"%(str(r),) )
218 elif __command == "Debug" and str(r) == "0":
219 __commands.append( "set( Concept='NoDebug' )" )
220 elif __command == "Debug" and str(r) == "1":
221 __commands.append( "set( Concept='Debug' )" )
222 elif __command == "ExecuteInContainer":
223 __suppparameters.update({'ExecuteInContainer':r})
225 elif __command == "UserPostAnalysis" and type(r) is dict:
227 __UserPostAnalysis = r['STRING'].replace("ADD.",str(self._objname)+".")
228 __commands.append( "set( Concept='UserPostAnalysis', String=\"\"\"%s\"\"\" )"%(__UserPostAnalysis,) )
229 elif 'SCRIPT_FILE' in r and os.path.exists(r['SCRIPT_FILE']):
230 __UserPostAnalysis = open(r['SCRIPT_FILE'],'r').read()
231 __commands.append( "set( Concept='UserPostAnalysis', Script='%s' )"%(r['SCRIPT_FILE'],) )
232 elif 'Template' in r and not 'ValueTemplate' in r:
234 if r['Template'] not in Templates.UserPostAnalysisTemplates:
235 raise ValueError("User post-analysis template \"%s\" does not exist."%(r['Template'],))
237 __UserPostAnalysis = Templates.UserPostAnalysisTemplates[r['Template']]
238 __commands.append( "set( Concept='UserPostAnalysis', Template='%s' )"%(r['Template'],) )
239 elif 'Template' in r and 'ValueTemplate' in r:
240 # Le template ayant pu être modifié, donc on ne prend que le ValueTemplate...
241 __UserPostAnalysis = r['ValueTemplate']
242 __commands.append( "set( Concept='UserPostAnalysis', String=\"\"\"%s\"\"\" )"%(__UserPostAnalysis,) )
244 __UserPostAnalysis = ""
246 elif __command == "AlgorithmParameters" and type(r) is dict and 'Algorithm' in r:
247 if 'data' in r and r['Parameters'] == 'Dict':
249 if 'STRING' in __from:
250 __parameters = ", Parameters=%s"%(repr(eval(__from['STRING'])),)
251 elif 'SCRIPT_FILE' in __from and os.path.exists(__from['SCRIPT_FILE']):
252 __parameters = ", Script='%s'"%(__from['SCRIPT_FILE'],)
253 else: # if 'Parameters' in r and r['Parameters'] == 'Defaults':
254 __Dict = copy.deepcopy(r)
255 __Dict.pop('Algorithm','')
256 __Dict.pop('Parameters','')
257 if 'SetSeed' in __Dict:__Dict['SetSeed'] = int(__Dict['SetSeed'])
258 if 'BoxBounds' in __Dict and type(__Dict['BoxBounds']) is str:
259 __Dict['BoxBounds'] = eval(__Dict['BoxBounds'])
261 __parameters = ', Parameters=%s'%(repr(__Dict),)
264 __commands.append( "set( Concept='AlgorithmParameters', Algorithm='%s'%s )"%(r['Algorithm'],__parameters) )
266 elif __command == "Observers" and type(r) is dict and 'SELECTION' in r:
267 if type(r['SELECTION']) is str:
268 __selection = (r['SELECTION'],)
270 __selection = tuple(r['SELECTION'])
271 for sk in __selection:
272 __idata = r['%s_data'%sk]
273 if __idata['NodeType'] == 'Template' and 'Template' in __idata:
274 __template = __idata['Template']
275 if 'Info' in __idata:
276 __info = ", Info='%s'"%(__idata['Info'],)
279 __commands.append( "set( Concept='Observer', Variable='%s', Template='%s'%s )"%(sk,__template,__info) )
280 if __idata['NodeType'] == 'String' and 'Value' in __idata:
281 __value =__idata['Value']
282 __commands.append( "set( Concept='Observer', Variable='%s', String='%s' )"%(sk,__value) )
284 # Background, ObservationError, ObservationOperator...
285 elif type(r) is dict:
287 if 'Stored' in r and bool(r['Stored']):
288 __argumentsList.append(['Stored',True])
289 if 'INPUT_TYPE' in r and 'data' in r:
290 # Vector, Matrix, ScalarSparseMatrix, DiagonalSparseMatrix, Function
291 __itype = r['INPUT_TYPE']
293 if 'FROM' in __idata:
294 # String, Script, DataFile, Template, ScriptWithOneFunction, ScriptWithFunctions
295 __ifrom = __idata['FROM']
296 __idata.pop('FROM','')
297 if __ifrom == 'String' or __ifrom == 'Template':
298 __argumentsList.append([__itype,__idata['STRING']])
299 if __ifrom == 'Script':
300 __argumentsList.append([__itype,True])
301 __argumentsList.append(['Script',__idata['SCRIPT_FILE']])
302 if __ifrom == 'DataFile':
303 __argumentsList.append([__itype,True])
304 __argumentsList.append(['DataFile',__idata['DATA_FILE']])
305 if __ifrom == 'ScriptWithOneFunction':
306 __argumentsList.append(['OneFunction',True])
307 __argumentsList.append(['Script',__idata.pop('SCRIPTWITHONEFUNCTION_FILE')])
309 __argumentsList.append(['Parameters',__idata])
310 if __ifrom == 'ScriptWithFunctions':
311 __argumentsList.append(['ThreeFunctions',True])
312 __argumentsList.append(['Script',__idata.pop('SCRIPTWITHFUNCTIONS_FILE')])
314 __argumentsList.append(['Parameters',__idata])
315 __arguments = ["%s = %s"%(k,repr(v)) for k,v in __argumentsList]
316 __commands.append( "set( Concept='%s', %s )"%(__command, ", ".join(__arguments)))
318 __commands.append( "set( Concept='%s', Parameters=%s )"%('SupplementaryParameters', repr(__suppparameters)))
320 # ----------------------------------------------------------------------
321 __commands.sort() # Pour commencer par 'AlgorithmParameters'
322 __commands.append(__UserPostAnalysis)
325 class _SCDViewer(GenericCaseViewer):
327 Établissement des commandes d'un cas SCD (Study Config Dictionary/Cas->SCD)
329 Remarque : le fichier généré est différent de celui obtenu par EFICAS
331 def __init__(self, __name="", __objname="case", __content=None, __object=None):
332 "Initialisation et enregistrement de l'entête"
333 GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
335 if __content is not None:
336 for command in __content:
337 if command[0] == "set": __command = command[2]["Concept"]
338 else: __command = command[0].replace("set", "", 1)
339 if __command == 'Name':
340 self._name = command[2]["String"]
342 self.__DebugCommandNotSet = True
343 self.__ObserverCommandNotSet = True
344 self.__UserPostAnalysisNotSet = True
346 self._addLine("# -*- coding: utf-8 -*-")
347 self._addLine("#\n# Input for ADAO converter to SCD\n#")
349 self._addLine("study_config = {}")
350 self._addLine("study_config['Name'] = '%s'"%self._name)
352 self._addLine("inputvariables_config = {}")
353 self._addLine("inputvariables_config['Order'] =['adao_default']")
354 self._addLine("inputvariables_config['adao_default'] = -1")
355 self._addLine("study_config['InputVariables'] = inputvariables_config")
357 self._addLine("outputvariables_config = {}")
358 self._addLine("outputvariables_config['Order'] = ['adao_default']")
359 self._addLine("outputvariables_config['adao_default'] = -1")
360 self._addLine("study_config['OutputVariables'] = outputvariables_config")
361 if __content is not None:
362 for command in __content:
363 self._append(*command)
364 def _append(self, __command=None, __keys=None, __local=None, __pre=None, __switchoff=False):
365 "Transformation d'une commande individuelle en un enregistrement"
366 if __command == "set": __command = __local["Concept"]
367 else: __command = __command.replace("set", "", 1)
368 logging.debug("SCD Order processed: %s"%(__command))
371 if __command in (None, 'execute', 'executePythonScheme', 'executeYACSScheme', 'get', 'Name'):
373 elif __command in ['Directory',]:
374 __text = "#\nstudy_config['Repertory'] = %s"%(repr(__local['String']))
375 elif __command in ['Debug', 'setDebug']:
376 __text = "#\nstudy_config['Debug'] = '1'"
377 self.__DebugCommandNotSet = False
378 elif __command in ['NoDebug', 'setNoDebug']:
379 __text = "#\nstudy_config['Debug'] = '0'"
380 self.__DebugCommandNotSet = False
381 elif __command in ['Observer', 'setObserver']:
382 if self.__ObserverCommandNotSet:
383 self._addLine("observers = {}")
384 self._addLine("study_config['Observers'] = observers")
385 self.__ObserverCommandNotSet = False
386 __obs = __local['Variable']
387 self._numobservers += 1
389 __text += "observers['%s'] = {}\n"%__obs
390 if __local['String'] is not None:
391 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
392 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, __local['String'])
393 if __local['Script'] is not None:
394 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'Script')
395 __text += "observers['%s']['Script'] = \"%s\"\n"%(__obs, __local['Script'])
396 if __local['Template'] is not None and __local['Template'] in Templates.ObserverTemplates:
397 __text += "observers['%s']['nodetype'] = '%s'\n"%(__obs, 'String')
398 __text += "observers['%s']['String'] = \"\"\"%s\"\"\"\n"%(__obs, Templates.ObserverTemplates[__local['Template']])
399 if __local['Info'] is not None:
400 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __local['Info'])
402 __text += "observers['%s']['info'] = \"\"\"%s\"\"\"\n"%(__obs, __obs)
403 __text += "observers['%s']['number'] = %s"%(__obs, self._numobservers)
404 elif __command in ['UserPostAnalysis', 'setUserPostAnalysis']:
406 __text += "Analysis_config = {}\n"
407 if __local['String'] is not None:
408 __text += "Analysis_config['From'] = 'String'\n"
409 __text += "Analysis_config['Data'] = \"\"\"%s\"\"\"\n"%(__local['String'],)
410 if __local['Script'] is not None:
411 __text += "Analysis_config['From'] = 'Script'\n"
412 __text += "Analysis_config['Data'] = \"\"\"%s\"\"\"\n"%(__local['Script'],)
413 if __local['Template'] is not None and __local['Template'] in Templates.UserPostAnalysisTemplates:
414 __text += "Analysis_config['From'] = 'String'\n"
415 __text += "Analysis_config['Data'] = \"\"\"%s\"\"\"\n"%(Templates.UserPostAnalysisTemplates[__local['Template']],)
416 __text += "study_config['UserPostAnalysis'] = Analysis_config"
417 self.__UserPostAnalysisNotSet = False
418 elif __local is not None: # __keys is not None and
419 numpy.set_printoptions(precision=15,threshold=1000000,linewidth=1000*15)
421 __text += "%s_config = {}\n"%__command
422 __local.pop('self','')
424 __vectorIsDataFile = False
425 __vectorIsScript = False
426 for __k,__v in __local.items():
427 if __v is None: __to_be_removed.append(__k)
428 for __k in __to_be_removed:
430 for __k,__v in __local.items():
431 if __k == "Concept": continue
432 if __k in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix','OneFunction','ThreeFunctions'] and 'Script' in __local and __local['Script'] is not None: continue
433 if __k in ['Vector','VectorSerie'] and 'DataFile' in __local and __local['DataFile'] is not None: continue
434 if __k == 'Parameters' and not (__command in ['AlgorithmParameters','SupplementaryParameters']): continue
435 if __k == 'Algorithm':
436 __text += "study_config['Algorithm'] = %s\n"%(repr(__v))
437 elif __k == 'DataFile':
440 __v = "'"+repr(__v)+"'"
441 for __lk in ['Vector','VectorSerie']:
442 if __lk in __local and __local[__lk]: __k = __lk
443 __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
444 __text += "%s_config['From'] = '%s'\n"%(__command,__f)
445 __text += "%s_config['Data'] = %s\n"%(__command,__v)
446 __text = __text.replace("''","'")
447 __vectorIsDataFile = True
448 elif __k == 'Script':
451 __v = "'"+repr(__v)+"'"
452 for __lk in ['ScalarSparseMatrix','DiagonalSparseMatrix','Matrix']:
453 if __lk in __local and __local[__lk]: __k = __lk
454 if __command == "AlgorithmParameters": __k = "Dict"
455 if 'OneFunction' in __local and __local['OneFunction']:
456 __text += "%s_ScriptWithOneFunction = {}\n"%(__command,)
457 __text += "%s_ScriptWithOneFunction['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
458 __text += "%s_ScriptWithOneFunction['Script'] = {}\n"%(__command,)
459 __text += "%s_ScriptWithOneFunction['Script']['Direct'] = %s\n"%(__command,__v)
460 __text += "%s_ScriptWithOneFunction['Script']['Tangent'] = %s\n"%(__command,__v)
461 __text += "%s_ScriptWithOneFunction['Script']['Adjoint'] = %s\n"%(__command,__v)
462 __text += "%s_ScriptWithOneFunction['DifferentialIncrement'] = 1e-06\n"%(__command,)
463 __text += "%s_ScriptWithOneFunction['CenteredFiniteDifference'] = 0\n"%(__command,)
465 __f = 'ScriptWithOneFunction'
466 __v = '%s_ScriptWithOneFunction'%(__command,)
467 if 'ThreeFunctions' in __local and __local['ThreeFunctions']:
468 __text += "%s_ScriptWithFunctions = {}\n"%(__command,)
469 __text += "%s_ScriptWithFunctions['Function'] = ['Direct', 'Tangent', 'Adjoint']\n"%(__command,)
470 __text += "%s_ScriptWithFunctions['Script'] = {}\n"%(__command,)
471 __text += "%s_ScriptWithFunctions['Script']['Direct'] = %s\n"%(__command,__v)
472 __text += "%s_ScriptWithFunctions['Script']['Tangent'] = %s\n"%(__command,__v)
473 __text += "%s_ScriptWithFunctions['Script']['Adjoint'] = %s\n"%(__command,__v)
475 __f = 'ScriptWithFunctions'
476 __v = '%s_ScriptWithFunctions'%(__command,)
477 __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
478 __text += "%s_config['From'] = '%s'\n"%(__command,__f)
479 __text += "%s_config['Data'] = %s\n"%(__command,__v)
480 __text = __text.replace("''","'")
481 __vectorIsScript = True
482 elif __k in ('Stored', 'Checked', 'ColMajor', 'InputFunctionAsMulti', 'nextStep'):
484 __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
485 elif __k in ('AvoidRC', 'noDetails'):
487 __text += "%s_config['%s'] = '%s'\n"%(__command,__k,int(bool(__v)))
489 if __k == 'Vector' and __vectorIsScript: continue
490 if __k == 'Vector' and __vectorIsDataFile: continue
491 if __k == 'Parameters': __k = "Dict"
492 if isinstance(__v,Persistence.Persistence): __v = __v.values()
493 if callable(__v): __text = self._missing%__v.__name__+__text
494 if isinstance(__v,dict):
495 for val in __v.values():
496 if callable(val): __text = self._missing%val.__name__+__text
497 __text += "%s_config['Type'] = '%s'\n"%(__command,__k)
498 __text += "%s_config['From'] = '%s'\n"%(__command,'String')
499 __text += "%s_config['Data'] = \"\"\"%s\"\"\"\n"%(__command,repr(__v))
500 __text += "study_config['%s'] = %s_config"%(__command,__command)
501 numpy.set_printoptions(precision=8,threshold=1000,linewidth=75)
503 self._switchoff = True
504 if __text is not None: self._addLine(__text)
506 self._switchoff = False
507 def _finalize(self, *__args):
508 self.__loadVariablesByScript()
510 self._addLine("Analysis_config = {}")
511 self._addLine("Analysis_config['From'] = 'String'")
512 self._addLine("Analysis_config['Data'] = \"\"\"import numpy")
513 self._addLine("xa=numpy.ravel(ADD.get('Analysis')[-1])")
514 self._addLine("print('Analysis:',xa)\"\"\"")
515 self._addLine("study_config['UserPostAnalysis'] = Analysis_config")
516 def __loadVariablesByScript(self):
517 __ExecVariables = {} # Necessaire pour recuperer la variable
518 exec("\n".join(self._lineSerie), __ExecVariables)
519 study_config = __ExecVariables['study_config']
520 # Pour Python 3 : self.__hasAlgorithm = bool(study_config['Algorithm'])
521 if 'Algorithm' in study_config:
522 self.__hasAlgorithm = True
524 self.__hasAlgorithm = False
525 if not self.__hasAlgorithm and \
526 "AlgorithmParameters" in study_config and \
527 isinstance(study_config['AlgorithmParameters'], dict) and \
528 "From" in study_config['AlgorithmParameters'] and \
529 "Data" in study_config['AlgorithmParameters'] and \
530 study_config['AlgorithmParameters']['From'] == 'Script':
531 __asScript = study_config['AlgorithmParameters']['Data']
532 __var = ImportFromScript(__asScript).getvalue( "Algorithm" )
533 __text = "#\nstudy_config['Algorithm'] = '%s'"%(__var,)
534 self._addLine(__text)
535 if self.__hasAlgorithm and \
536 "AlgorithmParameters" in study_config and \
537 isinstance(study_config['AlgorithmParameters'], dict) and \
538 "From" not in study_config['AlgorithmParameters'] and \
539 "Data" not in study_config['AlgorithmParameters']:
541 __text += "AlgorithmParameters_config['Type'] = 'Dict'\n"
542 __text += "AlgorithmParameters_config['From'] = 'String'\n"
543 __text += "AlgorithmParameters_config['Data'] = '{}'\n"
544 self._addLine(__text)
547 class _YACSViewer(GenericCaseViewer):
549 Etablissement des commandes d'un cas YACS (Cas->SCD->YACS)
551 def __init__(self, __name="", __objname="case", __content=None, __object=None):
552 "Initialisation et enregistrement de l'entete"
553 GenericCaseViewer.__init__(self, __name, __objname, __content, __object)
554 self.__internalSCD = _SCDViewer(__name, __objname, __content, __object)
555 self._append = self.__internalSCD._append
556 def dump(self, __filename=None, __upa=None):
557 "Restitution normalisée des commandes"
559 if __filename is None:
560 raise ValueError("A file name has to be given for YACS XML output.")
562 __file = os.path.abspath(__filename)
563 if os.path.isfile(__file) or os.path.islink(__file):
566 if not PlatformInfo.has_salome or \
567 not PlatformInfo.has_adao:
569 "Unable to get SALOME or ADAO environnement for YACS conversion.\n"+\
570 "Please load the right SALOME environnement before trying to use it.")
572 from daYacsSchemaCreator.run import create_schema_from_content
574 self.__internalSCD._finalize(__upa)
575 __SCDdump = self.__internalSCD.dump()
576 create_schema_from_content(__SCDdump, __file)
578 if not os.path.exists(__file):
579 __msg = "An error occured during the ADAO YACS Schema build for\n"
580 __msg += "the target output file:\n"
581 __msg += " %s\n"%__file
582 __msg += "See errors details in your launching terminal log.\n"
583 raise ValueError(__msg)
585 __fid = open(__file,"r")
586 __text = __fid.read()
590 # ==============================================================================
591 class ImportFromScript(object):
593 Obtention d'une variable nommee depuis un fichier script importé
595 __slots__ = ("__basename", "__filenspace", "__filestring")
596 def __init__(self, __filename=None):
597 "Verifie l'existence et importe le script"
598 if __filename is None:
599 raise ValueError("The name of the file, containing the variable to be read, has to be specified.")
600 if not os.path.isfile(__filename):
601 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))
602 if os.path.dirname(__filename) != '':
603 sys.path.insert(0, os.path.dirname(__filename))
604 __basename = os.path.basename(__filename).rstrip(".py")
606 __basename = __filename.rstrip(".py")
607 PlatformInfo.checkFileNameImportability( __basename+".py" )
608 self.__basename = __basename
609 self.__filenspace = __import__(__basename, globals(), locals(), [])
610 self.__filestring = open(__filename,'r').read()
611 def getvalue(self, __varname=None, __synonym=None ):
612 "Renvoie la variable demandee par son nom ou son synonyme"
613 if __varname is None:
614 raise ValueError("The name of the variable to be read has to be specified. Please check the content of the file and the syntax.")
615 if not hasattr(self.__filenspace, __varname):
616 if __synonym is None:
617 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))
618 elif not hasattr(self.__filenspace, __synonym):
619 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))
621 return getattr(self.__filenspace, __synonym)
623 return getattr(self.__filenspace, __varname)
625 "Renvoie le script complet"
626 return self.__filestring
628 # ==============================================================================
629 class ImportDetector(object):
631 Détection des caractéristiques de fichiers ou objets en entrée
634 "__url", "__usr", "__root", "__end")
635 def __enter__(self): return self
636 def __exit__(self, exc_type, exc_val, exc_tb): return False
638 def __init__(self, __url, UserMime=""):
640 raise ValueError("The name or url of the file object has to be specified.")
642 self.__url = __url.decode()
644 self.__url = str(__url)
645 if UserMime is bytes:
646 self.__usr = UserMime.decode().lower()
648 self.__usr = str(UserMime).lower()
649 (self.__root, self.__end) = os.path.splitext(self.__url)
651 mimetypes.add_type('application/numpy.npy', '.npy')
652 mimetypes.add_type('application/numpy.npz', '.npz')
653 mimetypes.add_type('application/dymola.sdf', '.sdf')
654 if sys.platform.startswith("win"):
655 mimetypes.add_type('text/plain', '.txt')
656 mimetypes.add_type('text/csv', '.csv')
657 mimetypes.add_type('text/tab-separated-values', '.tsv')
661 def is_local_file(self):
662 if os.path.isfile(os.path.realpath(self.__url)):
666 def is_not_local_file(self):
667 if not os.path.isfile(os.path.realpath(self.__url)):
671 def raise_error_if_not_local_file(self):
672 if not os.path.isfile(os.path.realpath(self.__url)):
673 raise ValueError("The name or the url of the file object doesn't seem to exist. The given name is:\n \"%s\""%str(self.__url))
677 # Directory related tests
678 # -----------------------
679 def is_local_dir(self):
680 if os.path.isdir(self.__url):
684 def is_not_local_dir(self):
685 if not os.path.isdir(self.__url):
689 def raise_error_if_not_local_dir(self):
690 if not os.path.isdir(self.__url):
691 raise ValueError("The name or the url of the directory object doesn't seem to exist. The given name is:\n \"%s\""%str(self.__url))
695 # Mime related functions
696 # ------------------------
697 def get_standard_mime(self):
698 (__mtype, __encoding) = mimetypes.guess_type(self.__url, strict=False)
700 def get_user_mime(self):
701 __fake = "fake."+self.__usr.lower()
702 (__mtype, __encoding) = mimetypes.guess_type(__fake, strict=False)
704 def get_comprehensive_mime(self):
705 if self.get_standard_mime() is not None:
706 return self.get_standard_mime()
707 elif self.get_user_mime() is not None:
708 return self.get_user_mime()
712 # Name related functions
713 # ----------------------
714 def get_user_name(self):
716 def get_absolute_name(self):
717 return os.path.abspath(os.path.realpath(self.__url))
718 def get_extension(self):
721 class ImportFromFile(object):
723 Obtention de variables disrétisées en 1D, définies par une ou des variables
724 nommées, et sous la forme d'une série de points éventuellement indexés. La
725 lecture d'un fichier au format spécifié (ou intuité) permet de charger ces
727 - des fichiers textes en colonnes de type TXT, CSV, TSV...
728 - des fichiers de données binaires NPY, NPZ, SDF...
729 La lecture du fichier complet ne se fait que si nécessaire, pour assurer la
730 performance tout en disposant de l'interprétation du contenu. Les fichiers
731 textes doivent présenter en première ligne (hors commentaire ou ligne vide)
732 les noms des variables de colonnes. Les commentaires commencent par un "#".
735 "_filename", "_colnames", "_colindex", "_varsline", "_format",
736 "_delimiter", "_skiprows", "__url", "__filestring", "__header",
737 "__allowvoid", "__binaryformats", "__supportedformats")
738 def __enter__(self): return self
739 def __exit__(self, exc_type, exc_val, exc_tb): return False
741 def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess", AllowVoidNameList=True):
743 Verifie l'existence et les informations de définition du fichier. Les
744 noms de colonnes ou de variables sont ignorées si le format ne permet
747 - Filename : nom du fichier
748 - ColNames : noms de la ou des colonnes/variables à lire
749 - ColIndex : nom unique de la colonne/variable servant d'index
750 - Format : format du fichier et/ou des données inclues
751 - AllowVoidNameList : permet, si la liste de noms est vide, de
752 prendre par défaut toutes les colonnes
754 self.__binaryformats =(
755 "application/numpy.npy",
756 "application/numpy.npz",
757 "application/dymola.sdf",
759 self.__url = ImportDetector( Filename, Format)
760 self.__url.raise_error_if_not_local_file()
761 self._filename = self.__url.get_absolute_name()
762 PlatformInfo.checkFileNameConformity( self._filename )
764 self._format = self.__url.get_comprehensive_mime()
766 self.__header, self._varsline, self._skiprows = self.__getentete()
768 if self._format == "text/csv" or Format.upper() == "CSV":
769 self._format = "text/csv"
770 self.__filestring = "".join(self.__header)
771 if self.__filestring.count(",") > 1:
772 self._delimiter = ","
773 elif self.__filestring.count(";") > 1:
774 self._delimiter = ";"
776 self._delimiter = None
777 elif self._format == "text/tab-separated-values" or Format.upper() == "TSV":
778 self._format = "text/tab-separated-values"
779 self._delimiter = "\t"
781 self._delimiter = None
783 if ColNames is not None: self._colnames = tuple(ColNames)
784 else: self._colnames = None
786 if ColIndex is not None: self._colindex = str(ColIndex)
787 else: self._colindex = None
789 self.__allowvoid = bool(AllowVoidNameList)
791 def __getentete(self, __nblines = 3):
792 "Lit l'entête du fichier pour trouver la définition des variables"
793 # La première ligne non vide non commentée est toujours considérée
794 # porter les labels de colonne, donc pas des valeurs
795 __header, __varsline, __skiprows = [], "", 1
796 if self._format in self.__binaryformats:
799 with open(self._filename,'r') as fid:
800 __line = fid.readline().strip()
801 while "#" in __line or len(__line) < 1:
802 __header.append(__line)
804 __line = fid.readline().strip()
806 for i in range(max(0,__nblines)):
807 __header.append(fid.readline())
808 return (__header, __varsline, __skiprows)
810 def __getindices(self, __colnames, __colindex, __delimiter=None ):
811 "Indices de colonnes correspondants à l'index et aux variables"
812 if __delimiter is None:
813 __varserie = self._varsline.strip('#').strip().split()
815 __varserie = self._varsline.strip('#').strip().split(str(__delimiter))
817 if __colnames is not None:
819 __colnames = tuple(__colnames)
821 for i, n in enumerate(__varserie):
822 if v == n: __usecols.append(i)
823 __usecols = tuple(__usecols)
824 if len(__usecols) == 0:
828 raise ValueError("Can not found any column corresponding to the required names %s"%(__colnames,))
832 if __colindex is not None:
834 __colindex = str(__colindex)
835 for i, n in enumerate(__varserie):
836 if __colindex == n: __useindex = i
840 return (__usecols, __useindex)
842 def getsupported(self):
843 self.__supportedformats = {}
844 self.__supportedformats["text/plain"] = True
845 self.__supportedformats["text/csv"] = True
846 self.__supportedformats["text/tab-separated-values"] = True
847 self.__supportedformats["application/numpy.npy"] = True
848 self.__supportedformats["application/numpy.npz"] = True
849 self.__supportedformats["application/dymola.sdf"] = PlatformInfo.has_sdf
850 return self.__supportedformats
852 def getvalue(self, ColNames=None, ColIndex=None ):
853 "Renvoie la ou les variables demandees par la liste de leurs noms"
854 # Uniquement si mise à jour
855 if ColNames is not None: self._colnames = tuple(ColNames)
856 if ColIndex is not None: self._colindex = str(ColIndex)
859 if self._format == "application/numpy.npy":
860 __columns = numpy.load(self._filename)
862 elif self._format == "application/numpy.npz":
864 with numpy.load(self._filename) as __allcolumns:
865 if self._colnames is None:
866 self._colnames = __allcolumns.files
867 for nom in self._colnames: # Si une variable demandée n'existe pas
868 if nom not in __allcolumns.files:
869 self._colnames = tuple( __allcolumns.files )
870 for nom in self._colnames:
871 if nom in __allcolumns.files:
872 if __columns is not None:
873 # Attention : toutes les variables doivent avoir la même taille
874 __columns = numpy.vstack((__columns, numpy.reshape(__allcolumns[nom], (1,-1))))
877 __columns = numpy.reshape(__allcolumns[nom], (1,-1))
878 if self._colindex is not None and self._colindex in __allcolumns.files:
879 __index = numpy.array(numpy.reshape(__allcolumns[self._colindex], (1,-1)), dtype=bytes)
880 elif self._format == "text/plain":
881 __usecols, __useindex = self.__getindices(self._colnames, self._colindex)
882 __columns = numpy.loadtxt(self._filename, usecols = __usecols, skiprows=self._skiprows)
883 if __useindex is not None:
884 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), skiprows=self._skiprows)
885 if __usecols is None: # Si une variable demandée n'existe pas
886 self._colnames = None
888 elif self._format == "application/dymola.sdf" and PlatformInfo.has_sdf:
890 __content = sdf.load(self._filename)
892 if self._colnames is None:
893 self._colnames = [__content.datasets[i].name for i in range(len(__content.datasets))]
894 for nom in self._colnames:
896 if __columns is not None:
897 # Attention : toutes les variables doivent avoir la même taille
898 __columns = numpy.vstack((__columns, numpy.reshape(__content[nom].data, (1,-1))))
901 __columns = numpy.reshape(__content[nom].data, (1,-1))
902 if self._colindex is not None and self._colindex in __content:
903 __index = __content[self._colindex].data
905 elif self._format == "text/csv":
906 __usecols, __useindex = self.__getindices(self._colnames, self._colindex, self._delimiter)
907 __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
908 if __useindex is not None:
909 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
910 if __usecols is None: # Si une variable demandée n'existe pas
911 self._colnames = None
913 elif self._format == "text/tab-separated-values":
914 __usecols, __useindex = self.__getindices(self._colnames, self._colindex, self._delimiter)
915 __columns = numpy.loadtxt(self._filename, usecols = __usecols, delimiter = self._delimiter, skiprows=self._skiprows)
916 if __useindex is not None:
917 __index = numpy.loadtxt(self._filename, dtype = bytes, usecols = (__useindex,), delimiter = self._delimiter, skiprows=self._skiprows)
918 if __usecols is None: # Si une variable demandée n'existe pas
919 self._colnames = None
921 raise ValueError("Unkown file format \"%s\" or no reader available"%self._format)
922 if __columns is None: __columns = ()
926 return value.decode()
929 if __index is not None:
930 __index = tuple([toString(v) for v in __index])
932 return (self._colnames, __columns, self._colindex, __index)
935 "Renvoie le fichier texte complet"
936 if self._format in self.__binaryformats:
939 with open(self._filename,'r') as fid:
945 class ImportScalarLinesFromFile(ImportFromFile):
947 Importation de fichier contenant des variables scalaires nommées. Le
948 fichier comporte soit 2, soit 4 colonnes, obligatoirement nommées "Name",
949 "Value", "Minimum", "Maximum" si les noms sont précisés. Sur chaque ligne
950 est indiqué le nom, la valeur, et éventuelement deux bornes min et max (ou
951 None si nécessaire pour une borne).
953 Seule la méthode "getvalue" est changée.
955 def __enter__(self): return self
956 def __exit__(self, exc_type, exc_val, exc_tb): return False
958 def __init__(self, Filename=None, ColNames=None, ColIndex=None, Format="Guess"):
959 ImportFromFile.__init__(self, Filename, ColNames, ColIndex, Format)
960 if self._format not in ["text/plain", "text/csv", "text/tab-separated-values"]:
961 raise ValueError("Unkown file format \"%s\""%self._format)
963 def getvalue(self, VarNames = None, HeaderNames=()):
964 "Renvoie la ou les variables demandees par la liste de leurs noms"
965 if VarNames is not None: __varnames = tuple(VarNames)
966 else: __varnames = None
968 if "Name" in self._varsline and "Value" in self._varsline and "Minimum" in self._varsline and "Maximum" in self._varsline:
969 __ftype = "NamValMinMax"
970 __dtypes = {'names' : ('Name', 'Value', 'Minimum', 'Maximum'),
971 'formats': ('S128', 'g', 'g', 'g')}
972 __usecols = (0, 1, 2, 3)
973 def __replaceNoneN( s ):
974 if s.strip() == b'None': return numpy.NINF
976 def __replaceNoneP( s ):
977 if s.strip() == b'None': return numpy.PINF
979 __converters = {2: __replaceNoneN, 3: __replaceNoneP}
980 elif "Name" in self._varsline and "Value" in self._varsline and ("Minimum" not in self._varsline or "Maximum" not in self._varsline):
982 __dtypes = {'names' : ('Name', 'Value'),
983 'formats': ('S128', 'g')}
986 elif len(HeaderNames)>0 and numpy.all([kw in self._varsline for kw in HeaderNames]):
987 __ftype = "NamLotOfVals"
988 __dtypes = {'names' : HeaderNames,
989 'formats': tuple(['S128',]+['g']*(len(HeaderNames)-1))}
990 __usecols = tuple(range(len(HeaderNames)))
991 def __replaceNone( s ):
992 if s.strip() == b'None': return numpy.NAN
994 __converters = dict()
995 for i in range(1,len(HeaderNames)):
996 __converters[i] = __replaceNone
998 raise ValueError("Can not find names of columns for initial values. Wrong first line is:\n \"%s\""%__firstline)
1000 if self._format == "text/plain":
1001 __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters)
1002 elif self._format in ["text/csv", "text/tab-separated-values"]:
1003 __content = numpy.loadtxt(self._filename, dtype = __dtypes, usecols = __usecols, skiprows = self._skiprows, converters = __converters, delimiter = self._delimiter)
1005 raise ValueError("Unkown file format \"%s\""%self._format)
1007 __names, __thevalue, __bounds = [], [], []
1008 for sub in __content:
1009 if len(__usecols) == 4:
1010 na, va, mi, ma = sub
1011 if numpy.isneginf(mi): mi = None # Réattribue les variables None
1012 elif numpy.isnan(mi): mi = None # Réattribue les variables None
1013 if numpy.isposinf(ma): ma = None # Réattribue les variables None
1014 elif numpy.isnan(ma): ma = None # Réattribue les variables None
1015 elif len(__usecols) == 2 and __ftype == "NamVal":
1021 for i, v in enumerate(nsub[1:]):
1022 if numpy.isnan(v): nsub[i+1] = None
1026 if (__varnames is None or na in __varnames) and (na not in __names):
1027 # Ne stocke que la premiere occurence d'une variable
1029 __thevalue.append(va)
1030 __bounds.append((mi,ma))
1032 __names = tuple(__names)
1033 __thevalue = numpy.array(__thevalue)
1034 __bounds = tuple(__bounds)
1036 return (__names, __thevalue, __bounds)
1038 # ==============================================================================
1039 class EficasGUI(object):
1041 Lancement autonome de l'interface EFICAS/ADAO
1043 def __init__(self, __addpath = None):
1044 # Chemin pour l'installation (ordre important)
1046 self.__path_settings_ok = False
1048 if "EFICAS_ROOT" in os.environ:
1049 __EFICAS_ROOT = os.environ["EFICAS_ROOT"]
1052 self.__msg += "\nKeyError:\n"+\
1053 " the required environment variable EFICAS_ROOT is unknown.\n"+\
1054 " You have either to be in SALOME environment, or to set\n"+\
1055 " this variable in your environment to the right path \"<...>\"\n"+\
1056 " to find an installed EFICAS application. For example:\n"+\
1057 " EFICAS_ROOT=\"<...>\" command\n"
1061 __path_ok = True and __path_ok
1063 self.__msg += "\nImportError:\n"+\
1064 " the required ADAO library can not be found to be imported.\n"+\
1065 " You have either to be in ADAO environment, or to be in SALOME\n"+\
1066 " environment, or to set manually in your Python 3 environment the\n"+\
1067 " right path \"<...>\" to find an installed ADAO application. For\n"+\
1069 " PYTHONPATH=\"<...>:${PYTHONPATH}\" command\n"
1073 __path_ok = True and __path_ok
1075 self.__msg += "\nImportError:\n"+\
1076 " the required PyQt5 library can not be found to be imported.\n"+\
1077 " You have either to have a raisonable up-to-date Python 3\n"+\
1078 " installation (less than 5 years), or to be in SALOME environment.\n"
1082 self.__msg += "\nWarning:\n"+\
1083 " It seems you have some troubles with your installation.\n"+\
1084 " Be aware that some other errors may exist, that are not\n"+\
1085 " explained as above, like some incomplete or obsolete\n"+\
1086 " Python 3, or incomplete module installation.\n"+\
1088 " Please correct the above error(s) before launching the\n"+\
1089 " standalone EFICAS/ADAO interface.\n"
1090 logging.debug("Some of the ADAO/EFICAS/QT5 paths have not been found")
1091 self.__path_settings_ok = False
1093 logging.debug("All the ADAO/EFICAS/QT5 paths have been found")
1094 self.__path_settings_ok = True
1096 if self.__path_settings_ok:
1097 sys.path.insert(0,__EFICAS_ROOT)
1098 sys.path.insert(0,os.path.join(adao.adao_py_dir,"daEficas"))
1099 if __addpath is not None and os.path.exists(os.path.abspath(__addpath)):
1100 sys.path.insert(0,os.path.abspath(__addpath))
1101 logging.debug("All the paths have been correctly set up")
1104 logging.debug("Errors in path settings have been found")
1107 if self.__path_settings_ok:
1108 logging.debug("Launching standalone EFICAS/ADAO interface...")
1109 from daEficas import prefs
1110 from InterfaceQT4 import eficas_go
1111 eficas_go.lanceEficas(code=prefs.code)
1113 logging.debug("Can not launch standalone EFICAS/ADAO interface for path errors.")
1115 # ==============================================================================
1116 if __name__ == "__main__":
1117 print('\n AUTODIAGNOSTIC\n')