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