Salome HOME
fin portage python 3
[tools/eficas.git] / convert / convert_TELEMAC.py
1 # Copyright (C) 2007-2013   EDF R&D
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19 from __future__ import absolute_import
20
21
22 import re
23 from Extensions.i18n import tr
24
25                                                                                         
26 from .convert_python import PythonParser
27 import six
28 from six.moves import range
29 try:
30   basestring
31 except NameError:
32   basestring = str
33
34 pattern_comment_slash   = re.compile(r"^\s*/")
35 pattern_eta   = re.compile(r".*&ETA.*")
36 pattern_fin   = re.compile(r".*&FIN.*")
37 pattern_oui   = re.compile(r"^\s*(oui|OUI|YES|yes|TRUE|VRAI)\s*$")
38 pattern_non   = re.compile(r"^\s*(non|NON|NO|no|FALSE|FAUX)\s*$")
39 pattern_blanc = re.compile(r"^\s*$")
40 pattern_listeVide = re.compile(r"^\s*'\s*'\s*$")
41 pattern_commence_par_quote=re.compile(r'^\s*[\'"].*')
42 pattern_finit_par_virgule_ou_affect=re.compile(r'^.*(,|;|=|:)\s*$')
43
44 pattern_ligne=re.compile(r'^\s*(?P<ident>[^=:]*)\s*[:=]\s*(?P<reste>.*)$')
45
46 pattern_variables=re.compile (r"^\s*(?P<ident>VARIABLES FOR GRAPHIC PRINTOUTS|VARIABLES POUR LES SORTIES GRAPHIQUES)\s*[:=]\s*(?P<valeur>[A-Za-z]+(\d*|\*)(,[A-Za-z]+(\d*|\*))*)\s*(?P<reste>.*)$")
47
48 # Attention aux listes de flottants
49 pattern_liste=re.compile(r'^\s*(?P<valeur>[+-.\w]+(\s*;\s*[+-.\w]+)+)\s*(?P<reste>.*)$')
50 pattern_liste_texte=re.compile(r"^\s*(?P<valeur>('.*(';\s*))+('.*'\s*)?)(?P<reste>.*)$")
51 pattern_flottant=re.compile(r'^\s*(?P<valeur>[+-]?((\d+(\.\d*)?)|(\.\d+))([dDeE][+-]?\d+)?)\s*(?P<reste>.*)$')
52 pattern_texteQuote  = re.compile (r"^\s*(?P<valeur>'[^']+(''[^']+)*')\s*(?P<reste>.*)$")
53 pattern_texteSimple = re.compile (r"(?P<valeur>(^|\s)\s*[\w\.-]+)\s*(?P<reste>.*)$")
54 pattern_texteVide   = re.compile (r"^\s*(?P<valeur>'')\s*(?P<reste>.*)$")
55
56 pattern_ContientDouble=re.compile (r"^.*''.*$")
57
58 # le pattern texte reconnait 
59 #nom1 nom 2 : ou = chaine entre ' 
60 # avec eventuellement  des quotes au milieu par exemple
61 # TITRE = 'TELEMAC 2D : GOUTTE D''EAU DANS UN BASSIN$'
62 # m.group("texte") va rendre 'TELEMAC 2D : GOUTTE D''EAU DANS UN BASSIN$' 
63
64
65 #Si le code n est pas Telemac
66 try :
67 #if 1 :
68    from aideAuxConvertisseurs import ListeSupprimeCasToEficas
69    from enumDicoTelemac       import TelemacdicoEn
70 except :
71    pass
72
73 from Extensions import localisation
74
75
76
77 def entryPoint():
78    """
79    Return a dictionary containing the description needed to load the plugin
80    """
81    return {
82           'name' : 'TELEMAC',
83           'factory' : TELEMACParser
84           }
85
86 class TELEMACParser(PythonParser):
87    """
88    This converter works like PythonParser, except that it also initializes all
89    model variables to None in order to avoid Python syntax errors when loading
90    a file with a different or inexistent definition of variables.
91    """
92
93    def convert(self, outformat, appli=None):
94  
95
96       from Accas import A_BLOC, A_FACT, A_SIMP
97       self.dicoCasToCata=appli.readercata.dicoCasToCata
98       self.dicoInverse=appli.readercata.dicoInverse
99       self.dicoMC=appli.readercata.dicoMC
100       self.Ordre_Des_Commandes=appli.readercata.Ordre_Des_Commandes
101
102       if appli.langue=='fr' :
103           from enumDicoTelemac       import DicoEnumCasFrToEnumCasEn
104           for k in DicoEnumCasFrToEnumCasEn :
105               TelemacdicoEn[k]=DicoEnumCasFrToEnumCasEn[k]
106
107       text=""
108       self.dictSimp={}
109
110       l_lignes_texte_all = self.text.split('\n')
111       l_lignes_texte = []
112       for l  in l_lignes_texte_all :
113         if not(pattern_comment_slash.match(l)): l_lignes_texte.append(l)
114
115       l_lignes=[]
116       i=0
117       while (i < len(l_lignes_texte)) :
118           ligne=l_lignes_texte[i]
119           i=i+1
120           if not(pattern_finit_par_virgule_ou_affect.match(ligne)):
121              l_lignes.append(ligne)
122              continue
123           nouvelle_ligne=ligne
124           while (i < len(l_lignes_texte)):
125              ligne_traitee=l_lignes_texte[i]
126              i=i+1
127              nouvelle_ligne += ligne_traitee
128              if not(pattern_finit_par_virgule_ou_affect.match(ligne_traitee)):
129                 l_lignes.append(nouvelle_ligne)
130                 break
131   
132
133       for ligne in l_lignes :
134           if pattern_comment_slash.match(ligne) : continue
135           if pattern_eta.match(ligne) : continue
136           if pattern_fin.match(ligne) : continue
137           if pattern_blanc.match(ligne) : continue
138  
139
140           finLigne=ligne
141           while finLigne != "" :
142               if pattern_comment_slash.match(finLigne) : finLigne=""; continue
143               valeur=""
144               if pattern_variables.match(finLigne) :
145                  m=pattern_variables.match(finLigne)
146                  simpCas=self.traiteIdent(m.group('ident'))
147                  valeur=m.group('valeur')
148                  finLigne=m.group('reste')
149                  self.dictSimp[simpCas]=valeur
150                  continue
151
152               
153               m=pattern_ligne.match(finLigne)
154               if m == None : 
155                  #print( "________________________________________________")
156                  print ('pb avec ****', finLigne , '**** dans ', ligne)
157                  #print( "________________________________________________")
158                  break
159       
160               simpCas=self.traiteIdent(m.group('ident'))
161               if not simpCas : 
162                  finLigne=m.group('reste')
163                  continue
164
165               finLigne=m.group('reste')
166               # attention, l ordre des if est important
167               if pattern_liste.match(finLigne) :
168                  m=pattern_liste.match(finLigne)
169               elif pattern_liste_texte.match(finLigne) :
170                  m=pattern_liste_texte.match(finLigne)
171               elif pattern_texteQuote.match(finLigne) :
172                  m=pattern_texteQuote.match(finLigne)
173               elif pattern_flottant.match(finLigne) : 
174                  m=pattern_flottant.match(finLigne)
175               elif pattern_texteVide.match(finLigne):
176                  m=pattern_texteVide.match(finLigne)
177               elif pattern_texteSimple.match(finLigne):
178                  m=pattern_texteSimple.match(finLigne)
179               else :
180                  #print ("________________________________________________")
181                  print ('pb avec ****', finLigne , '**** dans ', ligne)
182                  print ("non match")
183                  #print ("________________________________________________")
184                  break
185               
186
187               valeur=m.group('valeur')
188               if pattern_blanc.match(valeur) : valeur=None
189
190               if pattern_flottant.match(finLigne) : 
191                  valeur=re.sub("d","e",valeur)
192                  valeur=re.sub("D","E",valeur)
193
194               if pattern_liste.match(finLigne) or pattern_liste_texte.match(finLigne):
195                  valeur=valeur.split(";")
196
197
198               finLigne=m.group('reste')
199               self.dictSimp[simpCas]=valeur
200       
201       if 'TITLE' not in self.dictSimp :
202           import os
203           #self.dictSimp['TITLE']=os.path.basename(self.filename)
204       
205       dicoParMC={}
206       for simp in self.dictSimp:
207           if simp in TELEMACParser.__dict__ : TELEMACParser.__dict__[simp],(self,)
208
209       for simp in self.dictSimp:
210           if simp in ListeSupprimeCasToEficas: continue
211           if simp not in self.dicoInverse : 
212              #print ( "************")
213              print  ("pb avec dans dicoInverse", simp,'------')
214              #print  ("************")
215              continue
216           listeGenea=self.dicoInverse[simp]
217           listeGeneaReverse=[]
218           for (u,v) in listeGenea : 
219               if isinstance(v,A_BLOC.BLOC): continue
220               listeGeneaReverse.append(u)
221           listeGeneaReverse.reverse()
222           dicoTravail=dicoParMC
223           i=0
224           while i < len(listeGeneaReverse[0:-1]) : 
225             mot=listeGeneaReverse[i]
226             i=i+1
227             if mot not in dicoTravail: dicoTravail[mot]={}
228             dicoTravail=dicoTravail[mot]
229           dicoTravail[simp]=self.dictSimp[simp]
230         
231       self.textePy=""
232       listeMC=self.tri(list(dicoParMC.keys()))
233       for k in listeMC :
234           self.textePy += str(k )+ "("
235           self.traiteMC(dicoParMC[k])
236           self.textePy += ");\n"
237            
238               
239       appli.listeTelemac=self.dictSimp  
240       return self.textePy
241
242
243    #----------------------------------------
244    def traiteIdent(self,ident):
245    # enleve les espaces de part et autre
246    # traduit du langage Telemac vers le langage Catalogue
247    #----------------------------------------
248           while ident[-1] == " " or ident[-1] == '\t' : ident=ident[0:-1]
249           while ident[0]  == " " or ident[0]  == '\t' : ident=ident[1:]
250           try : identCata=self.dicoCasToCata[ident]
251           except :  
252             print ( "---> ", "pb mot clef  pour", ident)
253             identCata=None
254           return identCata
255
256
257    def traiteMC(self,dico) :
258        from Accas import A_BLOC, A_FACT, A_SIMP
259        for k in dico :
260            valeur= dico[k]
261            if k not in self.dicoMC : kA=self.dicoFrancaisAnglais[k] 
262            else : kA=k
263            obj=self.dicoMC[kA]
264            if isinstance(obj,A_FACT.FACT):   self.convertFACT(obj,kA,valeur)
265            elif isinstance(obj,A_BLOC.BLOC): self.convertBLOC(obj,kA,valeur)
266            elif isinstance(obj,A_SIMP.SIMP): self.convertSIMP(obj,kA,valeur)
267            else : print ("%%%%%%%%%%%\n", "pb conversion type pour", k, obj, "\n%%%%%%%%%%%")
268
269
270    def convertFACT(self,obj,nom,valeur):
271        if nom in TELEMACParser.__dict__ : 
272           TELEMACParser.__dict__[nom],(self,)
273           return
274        self.textePy +=  nom + "=_F( "
275        self.traiteMC(valeur)
276        self.textePy += '),\n'
277
278
279    def convertBLOC(self,obj,nom,valeur):
280        print ("ANOMALIE _________ BLOC ")
281        print (nom)
282
283    def convertSIMP(self,obj,nom,valeur):
284        #print 'in convertSIMP', nom,valeur
285        if nom in ("PRESCRIBED_FLOWRATES", "PRESCRIBED_VELOCITIES", "PRESCRIBED_ELEVATIONS" ): return
286        if obj.max==1 : 
287           if hasattr(obj.type[0],'ntuple') : 
288              lval=[]
289              for v in valeur : 
290                try :    v=eval(v,{})
291                except : pass
292                lval.append(v)
293              self.textePy += nom + "=" + str(lval) +","
294              return
295           if 'TXM' in obj.type :
296
297               if pattern_ContientDouble.match(str(valeur)):
298                  valeur=re.sub("''","\'\'",str(valeur))
299                  self.textePy += nom + "=" + str(valeur) +","
300                  return
301               valeur=str(valeur)
302
303               # ceinture et bretelle si les re sont correctes -)
304               while valeur[-1] == " " or valeur[-1] == '\t' : valeur=valeur[0:-1]
305               while valeur[0]  == " " or valeur[0]  == '\t' : valeur=valeur[1:]
306
307
308
309           # Pour les enum
310           try    : valeur=eval(valeur,{})
311           except : pass
312
313           if nom in TelemacdicoEn: 
314              try    : 
315                valeur=TelemacdicoEn[nom][valeur]
316                self.textePy += nom + "= '" + str(valeur) +"',"
317                return
318              except : pass
319
320
321           if obj.into != [] and obj.into != None and not('R' in obj.type) and not('I' in obj.type):
322              for possible in obj.into :
323                 try :
324                   if possible.upper() == valeur.upper():
325                      valeur=possible
326                      break
327                   v=valeur[0].upper()+valeur[1:].lower()
328                   v2=tr(v)
329                   if possible.upper() == v2.upper():
330                      valeur=possible
331                      break
332                 except:
333                    if valeur != None :
334                       print ("pb avec le type de ", obj.nom, obj.type, 'et la valeur ', valeur)
335
336           if 'Fichier' in obj.type or 'TXM' in obj.type or 'Repertoire' in obj.type :
337               valeur=str(valeur)
338               if valeur == "" or valeur == " " : 
339                  self.textePy += nom + "= '" + str(valeur) +"' ,"
340                  return
341               while valeur[-1] == " " : valeur=valeur[0:-1]
342               while valeur[0]  == " " : valeur=valeur[1:]
343               self.textePy += nom + "= '" + str(valeur) +"' ,"
344               return
345
346           if bool in obj.type :
347             if   valeur == True  :  self.textePy += nom + "= True,"
348             elif valeur == False :  self.textePy += nom + "= False,"
349             elif pattern_oui.match(valeur) : self.textePy += nom + "= True,"
350             elif pattern_non.match(valeur) : self.textePy += nom + "= False,"
351             else :  self.textePy += nom + "= None,"
352             return
353           self.textePy += nom + "=" + str(valeur) +","
354
355        else :
356           if valeur == () or valeur ==[] or pattern_listeVide.match(str(valeur)) :
357              self.textePy += nom + "= None,"
358              return
359
360           # les 4 lignes suivantes sont probablement inutiles
361           while valeur[-1] == " " or  valeur[-1]=="'" : valeur=valeur[0:-1]
362           while valeur[0]  == " " or  valeur[-0]=="'" : valeur=valeur[1:]
363           oldValeur=valeur
364           if isinstance(valeur, basestring) :
365              if   ";" in valeur : valeur=valeur.split(';')
366              else  : valeur=valeur.split(',')
367
368           if len(valeur)< 2 and pattern_flottant.match(oldValeur):
369           # Attention : on attend une liste mais on a une seule valeur!
370              try :    oldValeur=eval(oldValeur,{})
371              except : pass
372              if nom in TelemacdicoEn :  
373                 v=TelemacdicoEn[nom][oldValeur]
374                 self.textePy += nom + "= ('" + str(v) +"',),"
375              else :  
376                 self.textePy += nom + "= (" + str(oldValeur) +",),"
377              return
378            
379  
380           if valeur == None : return
381           newVal=[]
382           for v in valeur :
383             try :    v=eval(v,{})
384             except : pass
385             if nom in TelemacdicoEn:
386                try    : v=TelemacdicoEn[nom][v]
387                except : pass
388             newVal.append(v)
389           self.textePy += nom + "=" + str(newVal) +","
390           
391
392
393    def tri(self, listeIn):
394       if len(listeIn) == 1 : return listeIn
395       if self.Ordre_Des_Commandes == None : return listeIn
396       listeOut=[listeIn[0],]
397       for k in listeIn[1:]:
398           #k=str(self.dicoFrancaisAnglais[kF])
399           ordreK=self.Ordre_Des_Commandes.index(k)
400           i=0
401           while i < len(listeOut):
402              #ordreI=self.Ordre_Des_Commandes.index(self.dicoFrancaisAnglais[listeOut[i]])
403              ordreI=self.Ordre_Des_Commandes.index(listeOut[i])
404              if ordreK < ordreI : break
405              i=i+1
406           #listeOut.insert(i,kF)
407           listeOut.insert(i,k)
408       return listeOut
409
410    def LIQUID_BOUNDARIES(self):
411        texte_Boundaries="LIQUID_BOUNDARIES=( "
412        if 'PRESCRIBED_ELEVATIONS' in self.dictSimp: 
413               valeursPE=self.dictSimp["PRESCRIBED_ELEVATIONS"]
414               if not type(valeursPE)==list : valeursPE = (valeursPE,)
415               longueur=len(self.dictSimp["PRESCRIBED_ELEVATIONS"])
416        else : valeursPE=None
417        if 'PRESCRIBED_FLOWRATES' in self.dictSimp: 
418               valeursPF=self.dictSimp["PRESCRIBED_FLOWRATES"]
419               if not type(valeursPF)==list : valeursPF = (valeursPF,)
420               longueur=len(self.dictSimp["PRESCRIBED_FLOWRATES"])
421        else : valeursPF=None
422        if 'PRESCRIBED_VELOCITIES' in self.dictSimp: 
423               valeursPV=self.dictSimp["PRESCRIBED_VELOCITIES"]
424               if not type(valeursPV)==list : valeursPV = (valeursPV,)
425               longueur=len(self.dictSimp["PRESCRIBED_VELOCITIES"])
426        else : valeursPV=None
427
428        if valeursPE == None and valeursPF == None and valeursPV == None :
429              texte_Boundaries +="),\n"
430              return
431
432        if valeursPE == None or valeursPF == None or valeursPV == None :
433           listNulle=[]
434           for i in range(longueur) : listNulle.append('0') 
435
436
437        if valeursPE == None : valeursPE = listNulle
438        if valeursPF == None : valeursPF = listNulle
439        if valeursPV == None : valeursPV = listNulle
440       
441
442        for e in range(len(valeursPE)):
443           if valeursPE[e] != "" or valeursPE[e] != "\n" :
444             if eval(valeursPE[e],{}) != 0 : 
445                texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Elevations',\n"
446                texte_Boundaries += "PRESCRIBED_ELEVATIONS = " + str(valeursPE[e]) + "),\n"
447                continue
448
449           if valeursPF[e] != "" or valeursPF[e] != "\n" :
450             if eval(valeursPF[e],{}) != 0 : 
451                texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Flowrates',\n"
452                texte_Boundaries += "PRESCRIBED_FLOWRATES = " + str(valeursPF[e]) + "),\n"
453                continue
454                
455           if valeursPV[e] != "" or valeursPV[e] != "\n" :
456              if eval(valeursPV[e],{})!=0 : 
457                 texte_Boundaries += "_F( BOUNDARY_TYPE= 'Prescribed Velocity',\n"
458                 texte_Boundaries += "PRESCRIBED_VELOCITIES = " + str(valeursPV[e]) + "),\n"
459                 continue
460           print ("pb texte_Boundaries avec la valeur numero ", e)
461
462        texte_Boundaries +="),\n"
463        self.textePy += texte_Boundaries
464