Salome HOME
9862ff098d6275a7cdc5a9c7f29d9a9e15198181
[tools/eficas.git] / convert / convert_TELEMAC.py
1 # Copyright (C) 2007-2021   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 #import traceback
26 #traceback.print_stack()
27
28 from convert.convert_python import Pythonparser
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|true|vrai|VRAI)\s*$")
40 pattern_non   = re.compile(r"^\s*(non|NON|NO|no|FALSE|false|faux|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 #   from enum_Telemac2d_auto       import self.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    
94
95    def convert(self, outformat, appliEficas=None):
96
97
98       from Accas import A_BLOC, A_FACT, A_SIMP
99       try :
100         self.dicoCasToCata = appliEficas.readercata.dicoCasToCata
101       except :
102         self.dicoCasToCata = {}
103         print ('pas de dicoCasToCata')
104       self.dicoInverse              = appliEficas.readercata.dicoInverse
105       self.dicoMC                   = appliEficas.readercata.dicoMC
106       self.Ordre_Des_Commandes      = appliEficas.readercata.Ordre_Des_Commandes
107       try :
108         self.TelemacdicoEn            = appliEficas.readercata.TelemacdicoEn
109       except :
110         self.TelemacdicoEn = {}
111         print ('pas de TelemacdicoEn')
112       try :
113         self.DicoEnumCasFrToEnumCasEn = appliEficas.readercata.DicoEnumCasFrToEnumCasEn
114       except :
115         self.DicoEnumCasFrToEnumCasEn = {}
116         print ('pas de DicoEnumCasFrToEnumCasEn')
117       
118
119       if appliEficas.langue=='fr' :
120           #from enum_Telemac2d_auto       import DicoEnumCasFrToEnumCasEn
121           for k in self.DicoEnumCasFrToEnumCasEn :
122               self.TelemacdicoEn[k]=self.DicoEnumCasFrToEnumCasEn[k]
123
124       text=""
125       self.dictSimp={}
126
127       l_lignes_texte_all = self.text.split('\n')
128       l_lignes_texte = []
129       listeComment = []
130       dicoComment={}
131       dicoCommentSimp={}
132       dicoCommentMC={}
133       texteComment=""
134       debut=True
135       trouveComment = 0
136       for l  in l_lignes_texte_all :
137         if pattern_eta.match(l) : continue
138         if pattern_fin.match(l) : continue
139         if pattern_blanc.match(l) : continue
140
141         if not(pattern_comment_slash.match(l)):
142               l_lignes_texte.append(l)
143               if trouveComment :
144                  if debut:  dicoComment['debut']=texteComment
145                  else : dicoComment[l]=texteComment
146                  trouveComment = 0
147                  texteComment=""
148               if debut : debut = False
149
150         if pattern_comment_slash.match(l):
151              #if pattern_comment_slash_vide.match(l) : continue
152              if pattern_comment_tiret.match(l) : continue
153              texteComment+=l.replace ('/','',1)
154              texteComment+='\n'
155              trouveComment=1
156
157       if texteComment != "" : dicoComment['fin']= texteComment
158
159
160       l_lignes=[]
161       i=0
162       while (i < len(l_lignes_texte)) :
163           ligne=l_lignes_texte[i]
164           i=i+1
165           if not(pattern_finit_par_virgule_ou_affect.match(ligne)):
166              l_lignes.append(ligne)
167              continue
168           nouvelle_ligne=ligne
169           while (i < len(l_lignes_texte)):
170              ligne_traitee=l_lignes_texte[i]
171              i=i+1
172              nouvelle_ligne += ligne_traitee
173              if not(pattern_finit_par_virgule_ou_affect.match(ligne_traitee)):
174                 l_lignes.append(nouvelle_ligne)
175                 break
176
177
178       for ligne in l_lignes :
179           if pattern_comment_slash.match(ligne) : continue
180           #PN : deja teste
181           #if pattern_eta.match(ligne) : continue
182           #if pattern_fin.match(ligne) : continue
183           #if pattern_blanc.match(ligne) : continue
184
185
186           finLigne=ligne
187           while finLigne != "" :
188               if pattern_comment_slash.match(finLigne) : finLigne=""; continue
189               valeur=""
190               if pattern_variables.match(finLigne) :
191                  m=pattern_variables.match(finLigne)
192                  simpCas=self.traiteIdent(m.group('ident'))
193                  valeur=m.group('valeur')
194                  finLigne=m.group('reste')
195                  self.dictSimp[simpCas]=valeur
196                  continue
197
198
199               m=pattern_ligne.match(finLigne)
200               if m == None :
201                  #print( "________________________________________________")
202                  print ('pb avec ****', finLigne , '**** dans ', ligne)
203                  #print( "________________________________________________")
204                  break
205
206               simpCas=self.traiteIdent(m.group('ident'))
207               if not simpCas :
208                  finLigne=m.group('reste')
209                  continue
210
211               finLigne=m.group('reste')
212               # attention, l ordre des if est important
213               if pattern_liste.match(finLigne) :
214                  m=pattern_liste.match(finLigne)
215               elif pattern_liste_texte.match(finLigne) :
216                  m=pattern_liste_texte.match(finLigne)
217               elif pattern_texteQuote.match(finLigne) :
218                  m=pattern_texteQuote.match(finLigne)
219               elif pattern_flottant.match(finLigne) :
220                  m=pattern_flottant.match(finLigne)
221               elif pattern_texteVide.match(finLigne):
222                  m=pattern_texteVide.match(finLigne)
223               elif pattern_texteSimple.match(finLigne):
224                  m=pattern_texteSimple.match(finLigne)
225               else :
226                  #print ("________________________________________________")
227                  print ('pb avec ****', finLigne , '**** dans ', ligne)
228                  print ("non match")
229                  #print ("________________________________________________")
230                  break
231
232
233               valeur=m.group('valeur')
234               if pattern_blanc.match(valeur) : valeur=None
235
236               if pattern_flottant.match(finLigne) :
237                  valeur=re.sub("d","e",valeur)
238                  valeur=re.sub("D","E",valeur)
239
240               if pattern_liste.match(finLigne) or pattern_liste_texte.match(finLigne):
241                  valeur=valeur.split(";")
242
243
244               finLigne=m.group('reste')
245               self.dictSimp[simpCas]=valeur
246
247               if ligne in dicoComment.keys():
248                  dicoCommentSimp[simpCas]=dicoComment[ligne]
249
250       if 'TITLE' not in self.dictSimp :
251           import os
252           #self.dictSimp['TITLE']=os.path.basename(self.filename)
253
254
255       dicoParMC={}
256       for simp in self.dictSimp:
257           if simp in TELEMACparser.__dict__ : TELEMACparser.__dict__[simp](self,)
258
259       for simp in self.dictSimp:
260           if simp not in self.dicoInverse :
261              #print ( "************")
262              print  ("pb avec dans dicoInverse", simp,'------')
263              print("dicoInverse",sorted(self.dicoInverse.keys()))
264              #print  ("************")
265              continue
266           listeGenea=self.dicoInverse[simp]
267           listeGeneaReverse=[]
268           for (u,v) in listeGenea :
269               if isinstance(v,A_BLOC.BLOC): continue
270               listeGeneaReverse.append(u)
271           listeGeneaReverse.reverse()
272           dicoTravail=dicoParMC
273           i=0
274           if simp in dicoCommentSimp :
275              MC=listeGeneaReverse[0]
276              if MC in dicoCommentMC : dicoCommentMC[MC]+dicoCommentSimp[simp]
277              else                   : dicoCommentMC[MC]=dicoCommentSimp[simp]
278           while i < len(listeGeneaReverse[0:-1]) :
279             mot=listeGeneaReverse[i]
280             i=i+1
281             if mot not in dicoTravail: dicoTravail[mot]={}
282             dicoTravail=dicoTravail[mot]
283           dicoTravail[simp]=self.dictSimp[simp]
284
285       self.textePy=""
286       listeMC=self.tri(list(dicoParMC.keys()))
287       for k in listeMC :
288           if k in dicoCommentMC :
289                 commentaire="COMMENTAIRE("+repr(dicoCommentMC[k])+")\n"
290                 self.textePy+=commentaire
291           self.textePy += str(k )+ "("
292           self.traiteMC(dicoParMC[k])
293           self.textePy += ");\n"
294
295
296       # ne sert plus
297       #appliEficas.listeTelemac=self.dictSimp
298       appliEficas.listeTelemac={}
299       if 'debut' in dicoComment :
300           commentaire="COMMENTAIRE("+repr(dicoComment['debut'])+")\n"
301           self.textePy=commentaire+self.textePy
302       if 'fin' in dicoComment :
303           commentaire="COMMENTAIRE("+repr(dicoComment['fin'])+")\n"
304           self.textePy=self.textePy+commentaire
305
306       #print (self.textePy)
307       return self.textePy
308
309
310    #----------------------------------------
311    def traiteIdent(self,ident):
312    # enleve les espaces de part et autre
313    # traduit du langage Telemac vers le langage Catalogue
314    #----------------------------------------
315           while ident[-1] == " " or ident[-1] == '\t' : ident=ident[0:-1]
316           while ident[0]  == " " or ident[0]  == '\t' : ident=ident[1:]
317           try : identCata=self.dicoCasToCata[ident]
318           except :
319             print ( "---> ", "pb mot clef  pour", ident)
320             identCata=None
321           return identCata
322
323
324    def traiteMC(self,dico) :
325        from Accas import A_BLOC, A_FACT, A_SIMP
326        for k in dico :
327            valeur= dico[k]
328            if k not in self.dicoMC : kA=self.dicoFrancaisAnglais[k]
329            else : kA=k
330            obj=self.dicoMC[kA]
331            if isinstance(obj,A_FACT.FACT):   self.convertFACT(obj,kA,valeur)
332            elif isinstance(obj,A_BLOC.BLOC): self.convertBLOC(obj,kA,valeur)
333            elif isinstance(obj,A_SIMP.SIMP): self.convertSIMP(obj,kA,valeur)
334            else : print ("%%%%%%%%%%%\n", "pb conversion type pour", k, obj, "\n%%%%%%%%%%%")
335
336
337    def convertFACT(self,obj,nom,valeur):
338        # traitement LIQUID_BOUNDARIES
339        if nom in TELEMACparser.__dict__ :
340           TELEMACparser.__dict__[nom](self,)
341           return
342        self.textePy +=  nom + "=_F( "
343        self.traiteMC(valeur)
344        self.textePy += '),\n'
345
346
347    def convertBLOC(self,obj,nom,valeur):
348        print ("ANOMALIE _________ BLOC ")
349        print (nom)
350
351    def convertSIMP(self,obj,nom,valeur):
352        #print ('in convertSIMP', nom,valeur)
353        #if nom in ("PRESCRIBED_FLOWRATES", "PRESCRIBED_VELOCITIES", "PRESCRIBED_ELEVATIONS" ): return
354        if obj.max==1 :
355           if hasattr(obj.type[0],'ntuple') :
356              lval=[]
357              for v in valeur :
358                try :    v=eval(v,{})
359                except : pass
360                lval.append(v)
361              self.textePy += nom + "=" + str(lval) +","
362              return
363           if 'TXM' in obj.type :
364
365               if pattern_ContientDouble.match(str(valeur)):
366                  valeur=re.sub("''","\'\'",str(valeur))
367                  self.textePy += nom + "=" + str(valeur) +","
368                  return
369               valeur=str(valeur)
370
371               # ceinture et bretelle si les re sont correctes -)
372               while valeur[-1] == " " or valeur[-1] == '\t' : valeur=valeur[0:-1]
373               while valeur[0]  == " " or valeur[0]  == '\t' : valeur=valeur[1:]
374
375
376
377           # Pour les enum
378           try    : valeur=eval(valeur,{})
379           except : pass
380
381           if nom in self.TelemacdicoEn:
382              try    :
383                valeur=self.TelemacdicoEn[nom][valeur]
384                self.textePy += nom + "= '" + str(valeur) +"',"
385                return
386              except : pass
387
388
389           if obj.into != [] and obj.into != None and not('R' in obj.type) and not('I' in obj.type):
390              for possible in obj.into :
391                 try :
392                   if possible.upper() == valeur.upper():
393                      valeur=possible
394                      break
395                   v=valeur[0].upper()+valeur[1:].lower()
396                   v2=tr(v)
397                   if possible.upper() == v2.upper():
398                      valeur=possible
399                      break
400                 except:
401                    if valeur != None :
402                       print ("pb avec le type de ", obj.nom, obj.type, 'et la valeur ', valeur)
403
404           if 'Fichier' in obj.type or 'TXM' in obj.type or 'Repertoire' in obj.type or 'FichierOuRepertoire' in obj.type :
405               valeur=str(valeur)
406               if valeur == "" or valeur == " " :
407                  self.textePy += nom + "= '" + str(valeur) +"' ,"
408                  return
409               while valeur[-1] == " " : valeur=valeur[0:-1]
410               while valeur[0]  == " " : valeur=valeur[1:]
411               self.textePy += nom + "= '" + str(valeur) +"' ,"
412               return
413
414           if bool in obj.type :
415             if   valeur == True  :  self.textePy += nom + "= True,"
416             elif valeur == False :  self.textePy += nom + "= False,"
417             elif pattern_oui.match(valeur) : self.textePy += nom + "= True,"
418             elif pattern_non.match(valeur) : self.textePy += nom + "= False,"
419             else :  self.textePy += nom + "= None,"
420             return
421           self.textePy += nom + "=" + str(valeur) +","
422
423        else :
424           if valeur == () or valeur ==[] or pattern_listeVide.match(str(valeur)) :
425              self.textePy += nom + "= None,"
426              return
427
428           # les 4 lignes suivantes sont probablement inutiles
429           while valeur[-1] == " " or  valeur[-1]=="'" : valeur=valeur[0:-1]
430           while valeur[0]  == " " or  valeur[-0]=="'" : valeur=valeur[1:]
431           oldValeur=valeur
432           if isinstance(valeur, basestring) :
433              if   ";" in valeur : valeur=valeur.split(';')
434              else  : valeur=valeur.split(',')
435
436           if len(valeur)< 2 and pattern_flottant.match(oldValeur):
437           # Attention : on attend une liste mais on a une seule valeur!
438              try :    oldValeur=eval(oldValeur,{})
439              except : pass
440              if nom in self.TelemacdicoEn :
441                 v=self.TelemacdicoEn[nom][oldValeur]
442                 self.textePy += nom + "= ('" + str(v) +"',),"
443              else :
444                 self.textePy += nom + "= (" + str(oldValeur) +",),"
445              return
446
447
448           if valeur == None : return
449           newVal=[]
450           for v in valeur :
451             try :    v=eval(v,{})
452             except : pass
453             if nom in self.TelemacdicoEn:
454                try    : v=self.TelemacdicoEn[nom][v]
455                except : pass
456             newVal.append(v)
457           self.textePy += nom + "=" + str(newVal) +","
458
459
460
461    def tri(self, listeIn):
462       if len(listeIn) == 1 : return listeIn
463       if self.Ordre_Des_Commandes == None : return listeIn
464       listeOut=[listeIn[0],]
465       for k in listeIn[1:]:
466           #k=str(self.dicoFrancaisAnglais[kF])
467           ordreK=self.Ordre_Des_Commandes.index(k)
468           i=0
469           while i < len(listeOut):
470              #ordreI=self.Ordre_Des_Commandes.index(self.dicoFrancaisAnglais[listeOut[i]])
471              ordreI=self.Ordre_Des_Commandes.index(listeOut[i])
472              if ordreK < ordreI : break
473              i=i+1
474           #listeOut.insert(i,kF)
475           listeOut.insert(i,k)
476       return listeOut
477
478 #   def BOUNDARY_CONDITIONS(self):
479 #       texte_Boundaries="BOUNDARY_CONDITIONS=_F(LIQUID_BOUNDARIES=( "
480 #       if 'PRESCRIBED_ELEVATIONS' in self.dictSimp:
481 #              valeursPE=self.dictSimp["PRESCRIBED_ELEVATIONS"]
482 #              if not type(valeursPE)==list : valeursPE = (valeursPE,)
483 #              longueur=len(self.dictSimp["PRESCRIBED_ELEVATIONS"])
484 #       else : valeursPE=None
485 #       if 'PRESCRIBED_FLOWRATES' in self.dictSimp:
486 #              valeursPF=self.dictSimp["PRESCRIBED_FLOWRATES"]
487 #              if not type(valeursPF)==list : valeursPF = (valeursPF,)
488 #              longueur=len(self.dictSimp["PRESCRIBED_FLOWRATES"])
489 #       else : valeursPF=None
490 #       if 'PRESCRIBED_VELOCITIES' in self.dictSimp:
491 #              valeursPV=self.dictSimp["PRESCRIBED_VELOCITIES"]
492 #              if not type(valeursPV)==list : valeursPV = (valeursPV,)
493 #              longueur=len(self.dictSimp["PRESCRIBED_VELOCITIES"])
494 #       else : valeursPV=None
495 #
496 #       if valeursPE == None and valeursPF == None and valeursPV == None :
497 #             texte_Boundaries +="),\n"
498 #             return
499 #
500 #       if valeursPE == None or valeursPF == None or valeursPV == None :
501 #          listNulle=[]
502 #          for i in range(longueur) : listNulle.append('0')
503 #
504 #
505 #       if valeursPE == None : valeursPE = listNulle
506 #       if valeursPF == None : valeursPF = listNulle
507 #       if valeursPV == None : valeursPV = listNulle
508 #
509 #
510 #       for e in range(len(valeursPE)):
511 #          if valeursPE[e] != "" or valeursPE[e] != "\n" :
512 #            if eval(valeursPE[e],{}) != 0 :
513 #               texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Elevations',\n"
514 #               texte_Boundaries += "PRESCRIBED_ELEVATIONS = " + str(valeursPE[e]) + "),\n"
515 #               continue
516 #
517 #          if valeursPF[e] != "" or valeursPF[e] != "\n" :
518 #            if eval(valeursPF[e],{}) != 0 :
519 #               texte_Boundaries += "_F(BOUNDARY_TYPE = 'Prescribed Flowrates',\n"
520 #               texte_Boundaries += "PRESCRIBED_FLOWRATES = " + str(valeursPF[e]) + "),\n"
521 #               continue
522 #
523 #          if valeursPV[e] != "" or valeursPV[e] != "\n" :
524 #             if eval(valeursPV[e],{})!=0 :
525 #                texte_Boundaries += "_F( BOUNDARY_TYPE= 'Prescribed Velocity',\n"
526 #                texte_Boundaries += "PRESCRIBED_VELOCITIES = " + str(valeursPV[e]) + "),\n"
527 #                continue
528 #          print ("pb texte_Boundaries avec la valeur numero ", e)
529 #
530 #       texte_Boundaries +="),),"
531 #       self.textePy += texte_Boundaries
532 #