Salome HOME
pour telemac
[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_comment_slash_vide   = re.compile(r"^\s*/\s*$")
36 pattern_comment_tiret        = re.compile(r"^\s*/-*/$")
37 pattern_eta   = re.compile(r".*&ETA.*")
38 pattern_fin   = re.compile(r".*&FIN.*")
39 pattern_oui   = re.compile(r"^\s*(oui|OUI|YES|yes|TRUE|VRAI)\s*$")
40 pattern_non   = re.compile(r"^\s*(non|NON|NO|no|FALSE|FAUX)\s*$")
41 pattern_blanc = re.compile(r"^\s*$")
42 pattern_listeVide = re.compile(r"^\s*'\s*'\s*$")
43 pattern_commence_par_quote=re.compile(r'^\s*[\'"].*')
44 pattern_finit_par_virgule_ou_affect=re.compile(r'^.*(,|;|=|:)\s*$')
45
46 pattern_ligne=re.compile(r'^\s*(?P<ident>[^=:]*)\s*[:=]\s*(?P<reste>.*)$')
47
48 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>.*)$")
49
50 # Attention aux listes de flottants
51 pattern_liste=re.compile(r'^\s*(?P<valeur>[+-.\w]+(\s*;\s*[+-.\w]+)+)\s*(?P<reste>.*)$')
52 pattern_liste_texte=re.compile(r"^\s*(?P<valeur>('.*(';\s*))+('.*'\s*)?)(?P<reste>.*)$")
53 pattern_flottant=re.compile(r'^\s*(?P<valeur>[+-]?((\d+(\.\d*)?)|(\.\d+))([dDeE][+-]?\d+)?)\s*(?P<reste>.*)$')
54 pattern_texteQuote  = re.compile (r"^\s*(?P<valeur>'[^']+(''[^']+)*')\s*(?P<reste>.*)$")
55 pattern_texteSimple = re.compile (r"(?P<valeur>(^|\s)\s*[\w\.-]+)\s*(?P<reste>.*)$")
56 pattern_texteVide   = re.compile (r"^\s*(?P<valeur>'')\s*(?P<reste>.*)$")
57
58 pattern_ContientDouble=re.compile (r"^.*''.*$")
59
60 # le pattern texte reconnait 
61 #nom1 nom 2 : ou = chaine entre ' 
62 # avec eventuellement  des quotes au milieu par exemple
63 # TITRE = 'TELEMAC 2D : GOUTTE D''EAU DANS UN BASSIN$'
64 # m.group("texte") va rendre 'TELEMAC 2D : GOUTTE D''EAU DANS UN BASSIN$' 
65
66
67 #Si le code n est pas Telemac
68 try :
69 #if 1 :
70    from aideAuxConvertisseurs import ListeSupprimeCasToEficas
71    from enumDicoTelemac       import TelemacdicoEn
72 except :
73    pass
74
75 from Extensions import localisation
76
77
78
79 def entryPoint():
80    """
81    Return a dictionary containing the description needed to load the plugin
82    """
83    return {
84           'name' : 'TELEMAC',
85           'factory' : TELEMACParser
86           }
87
88 class TELEMACParser(PythonParser):
89    """
90    This converter works like PythonParser, except that it also initializes all
91    model variables to None in order to avoid Python syntax errors when loading
92    a file with a different or inexistent definition of variables.
93    """
94
95    def convert(self, outformat, appli=None):
96  
97
98       from Accas import A_BLOC, A_FACT, A_SIMP
99       self.dicoCasToCata=appli.readercata.dicoCasToCata
100       self.dicoInverse=appli.readercata.dicoInverse
101       self.dicoMC=appli.readercata.dicoMC
102       self.Ordre_Des_Commandes=appli.readercata.Ordre_Des_Commandes
103
104       if appli.langue=='fr' :
105           from enumDicoTelemac       import DicoEnumCasFrToEnumCasEn
106           for k in DicoEnumCasFrToEnumCasEn :
107               TelemacdicoEn[k]=DicoEnumCasFrToEnumCasEn[k]
108
109       text=""
110       self.dictSimp={}
111
112       l_lignes_texte_all = self.text.split('\n')
113       l_lignes_texte = []
114       listeComment = []
115       dicoComment={}
116       dicoCommentSimp={}
117       dicoCommentMC={}
118       texteComment=""
119       debut=True
120       for l  in l_lignes_texte_all :
121         if pattern_eta.match(l) : continue
122         if pattern_fin.match(l) : continue
123         if pattern_blanc.match(l) : continue
124
125         if not(pattern_comment_slash.match(l)): 
126               l_lignes_texte.append(l)
127               if trouveComment :
128                  if debut:  dicoComment['debut']=texteComment
129                  else : dicoComment[l]=texteComment
130                  trouveComment = 0
131                  texteComment=""
132               if debut : debut = False
133                  
134         if pattern_comment_slash.match(l):
135              #if pattern_comment_slash_vide.match(l) : continue
136              if pattern_comment_tiret.match(l) : continue
137              texteComment+=l.replace ('/','',1)
138              texteComment+='\n'
139              trouveComment=1
140   
141       if texteComment != "" : dicoComment['fin']= texteComment
142
143
144       l_lignes=[]
145       i=0
146       while (i < len(l_lignes_texte)) :
147           ligne=l_lignes_texte[i]
148           i=i+1
149           if not(pattern_finit_par_virgule_ou_affect.match(ligne)):
150              l_lignes.append(ligne)
151              continue
152           nouvelle_ligne=ligne
153           while (i < len(l_lignes_texte)):
154              ligne_traitee=l_lignes_texte[i]
155              i=i+1
156              nouvelle_ligne += ligne_traitee
157              if not(pattern_finit_par_virgule_ou_affect.match(ligne_traitee)):
158                 l_lignes.append(nouvelle_ligne)
159                 break
160   
161
162       for ligne in l_lignes :
163           if pattern_comment_slash.match(ligne) : continue
164           #PN : deja teste
165           #if pattern_eta.match(ligne) : continue
166           #if pattern_fin.match(ligne) : continue
167           #if pattern_blanc.match(ligne) : continue
168  
169
170           finLigne=ligne
171           while finLigne != "" :
172               if pattern_comment_slash.match(finLigne) : finLigne=""; continue
173               valeur=""
174               if pattern_variables.match(finLigne) :
175                  m=pattern_variables.match(finLigne)
176                  simpCas=self.traiteIdent(m.group('ident'))
177                  valeur=m.group('valeur')
178                  finLigne=m.group('reste')
179                  self.dictSimp[simpCas]=valeur
180                  continue
181
182               
183               m=pattern_ligne.match(finLigne)
184               if m == None : 
185                  #print( "________________________________________________")
186                  print ('pb avec ****', finLigne , '**** dans ', ligne)
187                  #print( "________________________________________________")
188                  break
189       
190               simpCas=self.traiteIdent(m.group('ident'))
191               if not simpCas : 
192                  finLigne=m.group('reste')
193                  continue
194
195               finLigne=m.group('reste')
196               # attention, l ordre des if est important
197               if pattern_liste.match(finLigne) :
198                  m=pattern_liste.match(finLigne)
199               elif pattern_liste_texte.match(finLigne) :
200                  m=pattern_liste_texte.match(finLigne)
201               elif pattern_texteQuote.match(finLigne) :
202                  m=pattern_texteQuote.match(finLigne)
203               elif pattern_flottant.match(finLigne) : 
204                  m=pattern_flottant.match(finLigne)
205               elif pattern_texteVide.match(finLigne):
206                  m=pattern_texteVide.match(finLigne)
207               elif pattern_texteSimple.match(finLigne):
208                  m=pattern_texteSimple.match(finLigne)
209               else :
210                  #print ("________________________________________________")
211                  print ('pb avec ****', finLigne , '**** dans ', ligne)
212                  print ("non match")
213                  #print ("________________________________________________")
214                  break
215               
216
217               valeur=m.group('valeur')
218               if pattern_blanc.match(valeur) : valeur=None
219
220               if pattern_flottant.match(finLigne) : 
221                  valeur=re.sub("d","e",valeur)
222                  valeur=re.sub("D","E",valeur)
223
224               if pattern_liste.match(finLigne) or pattern_liste_texte.match(finLigne):
225                  valeur=valeur.split(";")
226
227
228               finLigne=m.group('reste')
229               self.dictSimp[simpCas]=valeur
230
231               if ligne in dicoComment.keys():
232                  dicoCommentSimp[simpCas]=dicoComment[ligne]
233       
234       if 'TITLE' not in self.dictSimp :
235           import os
236           #self.dictSimp['TITLE']=os.path.basename(self.filename)
237       
238
239       dicoParMC={}
240       for simp in self.dictSimp:
241           if simp in TELEMACParser.__dict__ : TELEMACParser.__dict__[simp],(self,)
242
243       for simp in self.dictSimp:
244           if simp in ListeSupprimeCasToEficas: continue
245           if simp not in self.dicoInverse : 
246              #print ( "************")
247              print  ("pb avec dans dicoInverse", simp,'------')
248              #print  ("************")
249              continue
250           listeGenea=self.dicoInverse[simp]
251           listeGeneaReverse=[]
252           for (u,v) in listeGenea : 
253               if isinstance(v,A_BLOC.BLOC): continue
254               listeGeneaReverse.append(u)
255           listeGeneaReverse.reverse()
256           dicoTravail=dicoParMC
257           i=0
258           if simp in dicoCommentSimp :
259              MC=listeGeneaReverse[0]
260              if MC in dicoCommentMC : dicoCommentMC[MC]+dicoCommentSimp[simp]
261              else                   : dicoCommentMC[MC]=dicoCommentSimp[simp]
262           while i < len(listeGeneaReverse[0:-1]) : 
263             mot=listeGeneaReverse[i]
264             i=i+1
265             if mot not in dicoTravail: dicoTravail[mot]={}
266             dicoTravail=dicoTravail[mot]
267           dicoTravail[simp]=self.dictSimp[simp]
268         
269       self.textePy=""
270       listeMC=self.tri(list(dicoParMC.keys()))
271       for k in listeMC :
272           if k in dicoCommentMC : 
273                 commentaire="COMMENTAIRE("+repr(dicoCommentMC[k])+")\n"
274                 self.textePy+=commentaire
275           self.textePy += str(k )+ "("
276           self.traiteMC(dicoParMC[k])
277           self.textePy += ");\n"
278            
279               
280       appli.listeTelemac=self.dictSimp  
281       if 'debut' in dicoComment : 
282           commentaire="COMMENTAIRE("+repr(dicoComment['debut'])+")\n"
283           self.textePy=commentaire+self.textePy
284       if 'fin' in dicoComment : 
285           commentaire="COMMENTAIRE("+repr(dicoComment['fin'])+")\n"
286           self.textePy=self.textePy+commentaire
287
288       return self.textePy
289
290
291    #----------------------------------------
292    def traiteIdent(self,ident):
293    # enleve les espaces de part et autre
294    # traduit du langage Telemac vers le langage Catalogue
295    #----------------------------------------
296           while ident[-1] == " " or ident[-1] == '\t' : ident=ident[0:-1]
297           while ident[0]  == " " or ident[0]  == '\t' : ident=ident[1:]
298           try : identCata=self.dicoCasToCata[ident]
299           except :  
300             print ( "---> ", "pb mot clef  pour", ident)
301             identCata=None
302           return identCata
303
304
305    def traiteMC(self,dico) :
306        from Accas import A_BLOC, A_FACT, A_SIMP
307        for k in dico :
308            valeur= dico[k]
309            if k not in self.dicoMC : kA=self.dicoFrancaisAnglais[k] 
310            else : kA=k
311            obj=self.dicoMC[kA]
312            if isinstance(obj,A_FACT.FACT):   self.convertFACT(obj,kA,valeur)
313            elif isinstance(obj,A_BLOC.BLOC): self.convertBLOC(obj,kA,valeur)
314            elif isinstance(obj,A_SIMP.SIMP): self.convertSIMP(obj,kA,valeur)
315            else : print ("%%%%%%%%%%%\n", "pb conversion type pour", k, obj, "\n%%%%%%%%%%%")
316
317
318    def convertFACT(self,obj,nom,valeur):
319        if nom in TELEMACParser.__dict__ : 
320           TELEMACParser.__dict__[nom],(self,)
321           return
322        self.textePy +=  nom + "=_F( "
323        self.traiteMC(valeur)
324        self.textePy += '),\n'
325
326
327    def convertBLOC(self,obj,nom,valeur):
328        print ("ANOMALIE _________ BLOC ")
329        print (nom)
330
331    def convertSIMP(self,obj,nom,valeur):
332        #print 'in convertSIMP', nom,valeur
333        if nom in ("PRESCRIBED_FLOWRATES", "PRESCRIBED_VELOCITIES", "PRESCRIBED_ELEVATIONS" ): return
334        if obj.max==1 : 
335           if hasattr(obj.type[0],'ntuple') : 
336              lval=[]
337              for v in valeur : 
338                try :    v=eval(v,{})
339                except : pass
340                lval.append(v)
341              self.textePy += nom + "=" + str(lval) +","
342              return
343           if 'TXM' in obj.type :
344
345               if pattern_ContientDouble.match(str(valeur)):
346                  valeur=re.sub("''","\'\'",str(valeur))
347                  self.textePy += nom + "=" + str(valeur) +","
348                  return
349               valeur=str(valeur)
350
351               # ceinture et bretelle si les re sont correctes -)
352               while valeur[-1] == " " or valeur[-1] == '\t' : valeur=valeur[0:-1]
353               while valeur[0]  == " " or valeur[0]  == '\t' : valeur=valeur[1:]
354
355
356
357           # Pour les enum
358           try    : valeur=eval(valeur,{})
359           except : pass
360
361           if nom in TelemacdicoEn: 
362              try    : 
363                valeur=TelemacdicoEn[nom][valeur]
364                self.textePy += nom + "= '" + str(valeur) +"',"
365                return
366              except : pass
367
368
369           if obj.into != [] and obj.into != None and not('R' in obj.type) and not('I' in obj.type):
370              for possible in obj.into :
371                 try :
372                   if possible.upper() == valeur.upper():
373                      valeur=possible
374                      break
375                   v=valeur[0].upper()+valeur[1:].lower()
376                   v2=tr(v)
377                   if possible.upper() == v2.upper():
378                      valeur=possible
379                      break
380                 except:
381                    if valeur != None :
382                       print ("pb avec le type de ", obj.nom, obj.type, 'et la valeur ', valeur)
383
384           if 'Fichier' in obj.type or 'TXM' in obj.type or 'Repertoire' in obj.type :
385               valeur=str(valeur)
386               if valeur == "" or valeur == " " : 
387                  self.textePy += nom + "= '" + str(valeur) +"' ,"
388                  return
389               while valeur[-1] == " " : valeur=valeur[0:-1]
390               while valeur[0]  == " " : valeur=valeur[1:]
391               self.textePy += nom + "= '" + str(valeur) +"' ,"
392               return
393
394           if bool in obj.type :
395             if   valeur == True  :  self.textePy += nom + "= True,"
396             elif valeur == False :  self.textePy += nom + "= False,"
397             elif pattern_oui.match(valeur) : self.textePy += nom + "= True,"
398             elif pattern_non.match(valeur) : self.textePy += nom + "= False,"
399             else :  self.textePy += nom + "= None,"
400             return
401           self.textePy += nom + "=" + str(valeur) +","
402
403        else :
404           if valeur == () or valeur ==[] or pattern_listeVide.match(str(valeur)) :
405              self.textePy += nom + "= None,"
406              return
407
408           # les 4 lignes suivantes sont probablement inutiles
409           while valeur[-1] == " " or  valeur[-1]=="'" : valeur=valeur[0:-1]
410           while valeur[0]  == " " or  valeur[-0]=="'" : valeur=valeur[1:]
411           oldValeur=valeur
412           if isinstance(valeur, basestring) :
413              if   ";" in valeur : valeur=valeur.split(';')
414              else  : valeur=valeur.split(',')
415
416           if len(valeur)< 2 and pattern_flottant.match(oldValeur):
417           # Attention : on attend une liste mais on a une seule valeur!
418              try :    oldValeur=eval(oldValeur,{})
419              except : pass
420              if nom in TelemacdicoEn :  
421                 v=TelemacdicoEn[nom][oldValeur]
422                 self.textePy += nom + "= ('" + str(v) +"',),"
423              else :  
424                 self.textePy += nom + "= (" + str(oldValeur) +",),"
425              return
426            
427  
428           if valeur == None : return
429           newVal=[]
430           for v in valeur :
431             try :    v=eval(v,{})
432             except : pass
433             if nom in TelemacdicoEn:
434                try    : v=TelemacdicoEn[nom][v]
435                except : pass
436             newVal.append(v)
437           self.textePy += nom + "=" + str(newVal) +","
438           
439
440
441    def tri(self, listeIn):
442       if len(listeIn) == 1 : return listeIn
443       if self.Ordre_Des_Commandes == None : return listeIn
444       listeOut=[listeIn[0],]
445       for k in listeIn[1:]:
446           #k=str(self.dicoFrancaisAnglais[kF])
447           ordreK=self.Ordre_Des_Commandes.index(k)
448           i=0
449           while i < len(listeOut):
450              #ordreI=self.Ordre_Des_Commandes.index(self.dicoFrancaisAnglais[listeOut[i]])
451              ordreI=self.Ordre_Des_Commandes.index(listeOut[i])
452              if ordreK < ordreI : break
453              i=i+1
454           #listeOut.insert(i,kF)
455           listeOut.insert(i,k)
456       return listeOut
457
458    def LIQUID_BOUNDARIES(self):
459        texte_Boundaries="LIQUID_BOUNDARIES=( "
460        if 'PRESCRIBED_ELEVATIONS' in self.dictSimp: 
461               valeursPE=self.dictSimp["PRESCRIBED_ELEVATIONS"]
462               if not type(valeursPE)==list : valeursPE = (valeursPE,)
463               longueur=len(self.dictSimp["PRESCRIBED_ELEVATIONS"])
464        else : valeursPE=None
465        if 'PRESCRIBED_FLOWRATES' in self.dictSimp: 
466               valeursPF=self.dictSimp["PRESCRIBED_FLOWRATES"]
467               if not type(valeursPF)==list : valeursPF = (valeursPF,)
468               longueur=len(self.dictSimp["PRESCRIBED_FLOWRATES"])
469        else : valeursPF=None
470        if 'PRESCRIBED_VELOCITIES' in self.dictSimp: 
471               valeursPV=self.dictSimp["PRESCRIBED_VELOCITIES"]
472               if not type(valeursPV)==list : valeursPV = (valeursPV,)
473               longueur=len(self.dictSimp["PRESCRIBED_VELOCITIES"])
474        else : valeursPV=None
475
476        if valeursPE == None and valeursPF == None and valeursPV == None :
477              texte_Boundaries +="),\n"
478              return
479
480        if valeursPE == None or valeursPF == None or valeursPV == None :
481           listNulle=[]
482           for i in range(longueur) : listNulle.append('0') 
483
484
485        if valeursPE == None : valeursPE = listNulle
486        if valeursPF == None : valeursPF = listNulle
487        if valeursPV == None : valeursPV = listNulle
488       
489
490        for e in range(len(valeursPE)):
491           if valeursPE[e] != "" or valeursPE[e] != "\n" :
492             if eval(valeursPE[e],{}) != 0 : 
493                texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Elevations',\n"
494                texte_Boundaries += "PRESCRIBED_ELEVATIONS = " + str(valeursPE[e]) + "),\n"
495                continue
496
497           if valeursPF[e] != "" or valeursPF[e] != "\n" :
498             if eval(valeursPF[e],{}) != 0 : 
499                texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Flowrates',\n"
500                texte_Boundaries += "PRESCRIBED_FLOWRATES = " + str(valeursPF[e]) + "),\n"
501                continue
502                
503           if valeursPV[e] != "" or valeursPV[e] != "\n" :
504              if eval(valeursPV[e],{})!=0 : 
505                 texte_Boundaries += "_F( BOUNDARY_TYPE= 'Prescribed Velocity',\n"
506                 texte_Boundaries += "PRESCRIBED_VELOCITIES = " + str(valeursPV[e]) + "),\n"
507                 continue
508           print ("pb texte_Boundaries avec la valeur numero ", e)
509
510        texte_Boundaries +="),\n"
511        self.textePy += texte_Boundaries
512