From: Pascale Noyret Date: Wed, 29 Nov 2006 11:25:47 +0000 (+0000) Subject: Modifs avec la STA8.4 X-Git-Tag: V1_11b3^0 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=2754fe5fb358c43eeb46e693b6e233a6ec2cd88c;p=modules%2Feficas.git Modifs avec la STA8.4 --- diff --git a/Aster/Cata/Utilitai/Graph.py b/Aster/Cata/Utilitai/Graph.py index e4fa2a28..6cc8ab3d 100644 --- a/Aster/Cata/Utilitai/Graph.py +++ b/Aster/Cata/Utilitai/Graph.py @@ -1,4 +1,4 @@ -#@ MODIF Graph Utilitai DATE 24/05/2005 AUTEUR MCOURTOI M.COURTOIS +#@ MODIF Graph Utilitai DATE 02/05/2006 AUTEUR MCOURTOI M.COURTOIS # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -19,6 +19,7 @@ # ====================================================================== # RESPONSABLE MCOURTOI M.COURTOIS +__all__ = ['Graph', 'AjoutParaCourbe'] import sys import os @@ -104,12 +105,12 @@ class Graph: self.Tri = [] self.Titre = '' self.SousTitre = '' - self.Min_X = 1.e+99 - self.Max_X = -1.e+99 - self.Min_Y = 1.e+99 + self.Min_X = None + self.Max_X = None + self.Min_Y = None + self.Max_Y = None self.MinP_X = 1.e+99 # minimum > 0 pour les échelles LOG self.MinP_Y = 1.e+99 - self.Max_Y = -1.e+99 self.Legende_X = '' self.Legende_Y = '' self.Echelle_X = 'LIN' @@ -118,31 +119,56 @@ class Graph: self.Grille_Y = -1 # attributs que l'utilisateur ne doit pas modifier self.NbCourbe = len(self.Valeurs) - self.BBXmin = self.Min_X - self.BBXmax = self.Max_X - self.BBYmin = self.Min_Y - self.BBYmax = self.Max_Y + self.BBXmin = 1.e+99 + self.BBXmax = -1.e+99 + self.BBYmin = 1.e+99 + self.BBYmax = -1.e+99 # pour conserver les paramètres du dernier tracé self.LastTraceArgs = {} self.LastTraceFormat = '' - return + # ------------------------------------------------------------------------------ - def SetExtrema(self,marge=0., x0=None, x1=None, y0=None, y1=None): - """Remplit les limites du tracé (Min/Max_X/Y) avec les valeurs de la + def SetExtremaX(self,marge=0., x0=None, x1=None, force=True): + """Remplit les limites du tracé (Min/Max_X) avec les valeurs de la bounding box +/- avec une 'marge'*(Max-Min)/2. - x0,x1,y0,y1 permettent de modifier la bb. + x0,x1 permettent de modifier la bb. """ if x0<>None: self.BBXmin=min([self.BBXmin, x0]) if x1<>None: self.BBXmax=max([self.BBXmax, x1]) + + dx=max(self.BBXmax-self.BBXmin,0.01*self.BBXmax) + if dx == 0.: + dx = 1.e-6 + if force or self.Min_X==None: + self.Min_X = self.BBXmin - marge*dx/2. + if force or self.Max_X==None: + self.Max_X = self.BBXmax + marge*dx/2. + return + + def SetExtremaY(self,marge=0., y0=None, y1=None, force=True): + """Remplit les limites du tracé (Min/Max_Y) avec les valeurs de la + bounding box +/- avec une 'marge'*(Max-Min)/2. + y0,y1 permettent de modifier la bb. + """ if y0<>None: self.BBYmin=min([self.BBYmin, y0]) if y1<>None: self.BBYmax=max([self.BBYmax, y1]) - dx=max(self.BBXmax-self.BBXmin,0.01*self.BBXmax) - self.Min_X = self.BBXmin - marge*dx/2. - self.Max_X = self.BBXmax + marge*dx/2. dy=max(self.BBYmax-self.BBYmin,0.01*self.BBYmax) - self.Min_Y = self.BBYmin - marge*dy/2. - self.Max_Y = self.BBYmax + marge*dy/2. + if dy == 0.: + dy = 1.e-6 + if force or self.Min_Y==None: + self.Min_Y = self.BBYmin - marge*dy/2. + if force or self.Max_Y==None: + self.Max_Y = self.BBYmax + marge*dy/2. + return + + def SetExtrema(self,marge=0., x0=None, x1=None, y0=None, y1=None, force=True): + """Remplit les limites du tracé (Min/Max_X/Y) avec les valeurs de la + bounding box +/- avec une 'marge'*(Max-Min)/2. + x0,x1,y0,y1 permettent de modifier la bb. + """ + self.SetExtremaX(marge, x0, x1, force=force) + self.SetExtremaY(marge, y0, y1, force=force) return # ------------------------------------------------------------------------------ def AutoBB(self,debut=-1): @@ -269,7 +295,7 @@ class Graph: if opts<>{}: kargs['opts']=opts if not FORMAT in para.keys(): - print ' Format inconnu : %s' % FORMAT + UTMESS('A', 'Objet Graph', 'Format inconnu : %s' % FORMAT) else: kargs['fmod']=para[FORMAT]['mode'] self.LastTraceArgs = kargs.copy() @@ -333,12 +359,24 @@ class TraceGraph: # objet Graph sous-jacent self.Graph=graph # si Min/Max incohérents - if graph.Min_X > graph.Max_X or graph.Min_Y > graph.Max_Y: - graph.SetExtrema(marge=0.05) - if graph.Min_X < 0. and graph.Echelle_X=='LOG': - graph.Min_X=graph.MinP_X - if graph.Min_Y < 0. and graph.Echelle_Y=='LOG': - graph.Min_Y=graph.MinP_Y + if graph.Min_X==None or graph.Max_X==None or graph.Min_X > graph.Max_X: + graph.SetExtremaX(marge=0.05, force=True) + if graph.Min_Y==None or graph.Max_Y==None or graph.Min_Y > graph.Max_Y: + graph.SetExtremaY(marge=0.05, force=True) + + if graph.Echelle_X=='LOG': + graph.Grille_X=10 + # verif si Min<0 à cause de la marge + if graph.Min_X < 0.: + if graph.BBXmin < 0.: + UTMESS('A', 'Graph', 'On limite la fenetre aux abscisses positives.') + graph.Min_X=graph.MinP_X + if graph.Echelle_Y=='LOG': + graph.Grille_Y=10 + if graph.Min_Y < 0.: + if graph.BBYmin < 0.: + UTMESS('A', 'Graph', 'On limite la fenetre aux ordonnées positives.') + graph.Min_Y=graph.MinP_Y # formats de base (identiques à ceux du module Table) self.DicForm={ @@ -355,7 +393,7 @@ class TraceGraph: # let's go self.Trace() - return + # ------------------------------------------------------------------------------ def __del__(self): """Fermeture du(des) fichier(s) à la destruction""" @@ -380,19 +418,19 @@ class TraceGraph: # ------------------------------------------------------------------------------ def Entete(self): """Retourne l'entete""" - raise StandardError, "Cette méthode doit etre définie par la classe fille." + raise NotImplementedError, "Cette méthode doit etre définie par la classe fille." # ------------------------------------------------------------------------------ def DescrCourbe(self,**args): """Retourne la chaine de caractères décrivant les paramètres de la courbe. """ - raise StandardError, "Cette méthode doit etre définie par la classe fille." + raise NotImplementedError, "Cette méthode doit etre définie par la classe fille." # ------------------------------------------------------------------------------ def Trace(self): """Méthode pour 'tracer' l'objet Graph dans un fichier. Met en page l'entete, la description des courbes et les valeurs selon le format et ferme le fichier. """ - raise StandardError, "Cette méthode doit etre définie par la classe fille." + raise NotImplementedError, "Cette méthode doit etre définie par la classe fille." # ------------------------------------------------------------------------------ @@ -420,12 +458,12 @@ class TraceTableau(TraceGraph): max0=max(abs(t0)) for i in range(1,g.NbCourbe): if g.Courbe(i)['NbPts']<>g.Courbe(0)['NbPts']: - msg.append(" La courbe %d n'a pas le meme " \ + msg.append("La courbe %d n'a pas le meme " \ "nombre de points que la 1ère." % i) else: ti=Numeric.array(g.Courbe(i)['Abs']) if max(abs((ti-t0).flat)) > self.EPSILON*max0: - msg.append(" Courbe %d : écart entre les "\ + msg.append("Courbe %d : écart entre les "\ "abscisses supérieur à %9.2E" % (i+1,self.EPSILON)) msg.append(" Utilisez IMPR_FONCTION pour interpoler " \ "les valeurs sur la première liste d'abscisses.") @@ -462,7 +500,7 @@ class TraceTableau(TraceGraph): Tab.Impr(FICHIER=self.NomFich[0], FORMAT='TABLEAU') # erreurs ? if msg: - print '\n'.join(msg) + UTMESS('A', 'Graph.TraceTableau', '\n'.join(msg)) return # ------------------------------------------------------------------------------ @@ -796,23 +834,29 @@ class TraceXmgrace(TraceGraph): Met en page l'entete, la description des courbes et les valeurs selon le format et ferme le fichier. """ - g=self.Graph - if self.PILOTE=='INTERACTIF': - self.NomFich[0]='Trace_'+time.strftime('%y%m%d%H%M%S',time.localtime())+'.dat' - self.Fich[0]=open(self.NomFich[0],'w') + g = self.Graph + if self.PILOTE == 'INTERACTIF': + self.NomFich[0] = 'Trace_%s.dat' % time.strftime('%y%m%d%H%M%S',time.localtime()) + self.Fich[0] = open(self.NomFich[0],'w') # initialise le graph self._FermFich() nbsets, x0, x1, y0, y1 = IniGrace(self.NomFich[0]) NumSetIni = nbsets+1 - g.SetExtrema(0.05, x0, x1, y0, y1) + g.SetExtrema(0.05, x0, x1, y0, y1, force=False) # si Min/Max incohérents - if g.Min_X < 0. and g.Echelle_X=='LOG': - g.Min_X=g.MinP_X - if g.Min_Y < 0. and g.Echelle_Y=='LOG': - g.Min_Y=g.MinP_Y + if g.Echelle_X=='LOG': + g.Grille_X=10 + if g.Min_X < 0.: + if g.BBXmin < 0.: + UTMESS('A', 'TraceXmgrace', 'On limite la fenetre aux abscisses positives.') + g.Min_X=g.MinP_X + if g.Echelle_Y=='LOG': + g.Grille_Y=10 + if g.Min_Y < 0.: + if g.BBYmin < 0.: + UTMESS('A', 'TraceXmgrace', 'On limite la fenetre aux ordonnées positives.') + g.Min_Y=g.MinP_Y - self._OuvrFich() - fich=self.Fich[0] if g.NbCourbe < 1: self._FermFich() return @@ -826,9 +870,13 @@ class TraceXmgrace(TraceGraph): g.Grille_X=int(round(g.Grille_X)) if deltaY>4: g.Grille_Y=int(round(g.Grille_Y)) + if g.Grille_X == 0.: + g.Grille_X = 1.e-6 + if g.Grille_Y == 0.: + g.Grille_Y = 1.e-6 # entete - fich.write('\n'.join(self.Entete())) - fich.write('\n') + content = self.Entete() + content.append('') # valeurs it=-1 for i in range(g.NbCourbe): @@ -836,62 +884,66 @@ class TraceXmgrace(TraceGraph): for k in range(dCi['NbCol']-1): it=it+1 dCi['NumSet'] = NumSetIni + it - fich.write('\n'.join(self.DescrCourbe(**dCi))) - fich.write('\n') + content.extend(self.DescrCourbe(**dCi)) + content.append('') # partie données (.dat) - lig=[] it=-1 for i in range(g.NbCourbe): dCi=g.Courbe(i) for k in range(dCi['NbCol']-1): it=it+1 - lig.append('@target g0.s%d' % (NumSetIni + it)) - lig.append('@type xy') + content.append('@target g0.s%d' % (NumSetIni + it)) + content.append('@type xy') listX, listY = Tri(g.Tri, lx=dCi['Abs'], ly=dCi['Ord'][k]) for j in range(dCi['NbPts']): - svX=self.DicForm['formR'] % listX[j] - svY=self.DicForm['formR'] % listY[j] - lig.append(self.DicForm['formR'] % listX[j] + \ + svX = self.DicForm['formR'] % listX[j] + svY = self.DicForm['formR'] % listY[j] + content.append(self.DicForm['formR'] % listX[j] + \ ' ' + self.DicForm['formR'] % listY[j]) - lig.append('&') - fich.write('\n'.join(lig)) - fich.write('\n') - self._FermFich() + content.append('&') + content.append('') # Production du fichier postscript, jpeg ou lancement interactif pilo=self.PILOTE - if self.PILOTE<>'': + if pilo == '': + self._OuvrFich() + self.Fich[0].write('\n'.join(content)) + self._FermFich() + else: xmgr=os.path.join(aster.repout(),'xmgrace') - nfhard=self.NomFich[0]+'.hardcopy' + nfwrk = self.NomFich[0]+'.wrk' + open(nfwrk, 'w').write('\n'.join(content)) + nfhard = self.NomFich[0]+'.hardcopy' # nom exact du pilote - if pilo=='POSTSCRIPT': - pilo='PostScript' - elif pilo=='INTERACTIF': - pilo='X11' + if pilo == 'POSTSCRIPT': + pilo = 'PostScript' + elif pilo == 'INTERACTIF': + pilo = 'X11' # ligne de commande - if pilo=='X11': - lcmde=xmgr+' '+self.NomFich[0] + if pilo == 'X11': + lcmde = '%s %s' % (xmgr, nfwrk) if not os.environ.has_key('DISPLAY') or os.environ['DISPLAY']=='': os.environ['DISPLAY']=':0.0' UTMESS('A','TraceXmgrace','Variable DISPLAY non définie') UTMESS('I','TraceXmgrace','on fixe le DISPLAY à %s' % os.environ['DISPLAY']) else: if os.path.exists(os.path.join(aster.repout(),'gracebat')): - xmgr=os.path.join(aster.repout(),'gracebat') - lcmde=xmgr+' -hdevice '+pilo+' -hardcopy -printfile '+nfhard+' '+self.NomFich[0] + xmgr = os.path.join(aster.repout(),'gracebat') + lcmde = '%s -hdevice %s -hardcopy -printfile %s %s' % (xmgr, pilo, nfhard, nfwrk) # appel xmgrace UTMESS('I','TraceXmgrace','Lancement de : '+lcmde) if not os.path.exists(xmgr): UTMESS('S','TraceXmgrace','Fichier inexistant : '+xmgr) - iret=os.system(lcmde) - if iret==0 or os.path.exists(nfhard): - if pilo not in ['','X11']: - os.remove(self.NomFich[0]) # necessaire sous windows - os.rename(nfhard,self.NomFich[0]) + iret = os.system(lcmde) + if iret == 0 or os.path.exists(nfhard): + if pilo not in ('', 'X11'): + new = open(nfhard, 'r').read() + open(self.NomFich[0], 'a').write(new) else: - UTMESS('A','TraceXmgrace',"Erreur lors de l'utilisation du filtre "+pilo+"\nLe fichier retourné est le fichier '.agr'") + UTMESS('A','TraceXmgrace', "Erreur lors de l'utilisation du filtre %s" \ + "\nLe fichier retourné est le fichier '.agr'" % pilo) # menage - if self.PILOTE=='INTERACTIF': + if self.PILOTE == 'INTERACTIF': os.remove(self.NomFich[0]) return @@ -1142,10 +1194,14 @@ def IniGrace(fich): fnew.write(line) fpre.close() fnew.close() - print """ + try: + UTMESS('I', 'Graph.IniGrace', """ Informations sur le fichier '%s' : Nombre de courbes : %3d Bornes des abscisses : [ %13.6G , %13.6G ] Bornes des ordonnées : [ %13.6G , %13.6G ] -""" % (fich, ns, x0, x1, y0, y1) +""" % (fich, ns, x0, x1, y0, y1)) + except TypeError: + # pas un format xmgrace + pass return ns, x0, x1, y0, y1 diff --git a/Aster/Cata/Utilitai/Table.py b/Aster/Cata/Utilitai/Table.py index b923acf3..9ad24144 100644 --- a/Aster/Cata/Utilitai/Table.py +++ b/Aster/Cata/Utilitai/Table.py @@ -1,4 +1,4 @@ -#@ MODIF Table Utilitai DATE 17/05/2005 AUTEUR DURAND C.DURAND +#@ MODIF Table Utilitai DATE 06/11/2006 AUTEUR MCOURTOI M.COURTOIS # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -19,22 +19,29 @@ # ====================================================================== # RESPONSABLE MCOURTOI M.COURTOIS +__all__ = ['Table', 'merge'] import sys -import string import re +from copy import copy -from types import * -EnumTypes=(ListType, TupleType) -NumberTypes=(IntType, LongType, FloatType, ComplexType) +from types import ListType, TupleType, IntType, LongType, FloatType, ComplexType, \ + DictType, StringType, StringTypes, UnicodeType, NoneType +EnumTypes = (ListType, TupleType) +NumberTypes = (IntType, LongType, FloatType, ComplexType) + +import transpose # try/except pour utiliser hors aster try: from Utilitai.Utmess import UTMESS except ImportError: def UTMESS(code,sprg,texte): - fmt='\n <%s> <%s> %s\n\n' - print fmt % (code,sprg,texte) + fmt = '\n <%s> <%s> %s\n\n' + if code == 'F': + raise StandardError, fmt % (code,sprg,texte) + else: + print fmt % (code,sprg,texte) if not sys.modules.has_key('Graph'): try: @@ -43,15 +50,18 @@ if not sys.modules.has_key('Graph'): import Graph # formats de base (identiques à ceux du module Graph) -DicForm={ +DicForm = { 'csep' : ' ', # séparateur 'ccom' : '#', # commentaire 'cdeb' : '', # début de ligne 'cfin' : '\n', # fin de ligne + 'sepch' : ';', # séparateur entre deux lignes d'une cellule 'formK' : '%-8s', # chaines 'formR' : '%12.5E', # réels 'formI' : '%8d' # entiers } +# type par défaut des chaines de caractères +Kdef = 'K24' # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ @@ -61,13 +71,26 @@ class TableBase(object): (c'est surtout utile pour vérifier que l'extraction et les filtres sur les colonnes sont corrects). """ + def __init__(self): + """Constructeur. + """ + self.rows=None + self.para=None + self.type=None + self.titr=None + def __repr__(self): return self.ReprTable() - def Croise(self,**kargs): - raise StandardError, 'Must be defined in a derived class' + def Croise(self, **kargs): + raise NotImplementedError, 'Must be defined in a derived class' + + def __len__(self): + """Retourne le nombre de ligne dans la Table/Colonne. + """ + return len(self.rows) # ------------------------------------------------------------------------------ - def Impr(self,FICHIER=None,FORMAT='TABLEAU',dform=None,**opts): + def Impr(self, FICHIER=None, FORMAT='TABLEAU', dform=None, **opts): """Impresssion de la Table selon le format spécifié. FICHIER : nom du(des) fichier(s). Si None, on dirige vers stdout dform : dictionnaire de formats d'impression (format des réels, @@ -87,7 +110,7 @@ class TableBase(object): 'dform' : DicForm.copy(), 'mode' : para[FORMAT]['mode'], } - if dform<>None and type(dform)==DictType: + if dform != None and type(dform) == DictType: kargs['dform'].update(dform) # ajout des options kargs.update(opts) @@ -98,36 +121,36 @@ class TableBase(object): else: if not type(kargs['PAGINATION']) in EnumTypes: - ppag=[kargs['PAGINATION'],] + ppag = [kargs['PAGINATION'],] else: - ppag=list(kargs['PAGINATION']) + ppag = list(kargs['PAGINATION']) del kargs['PAGINATION'] - npag=len(ppag) + npag = len(ppag) # paramètres hors ceux de la pagination - lkeep=[p for p in self.para if ppag.count(p)==0] + lkeep = [p for p in self.para if ppag.count(p)==0] # création des listes des valeurs distinctes - lvd=[] + lvd = [] for p in ppag: - lvp=getattr(self,p).values() - lvn=[] + lvp = getattr(self,p).values() + lvn = [] for it in lvp: - if it<>None and lvn.count(it)==0: + if it != None and lvn.count(it) == 0: lvn.append(it) lvn.sort() lvd.append(lvn) # création des n-uplets - s = '[['+','.join(['x'+str(i) for i in range(npag)])+'] ' - s+= ' '.join(['for x'+str(i)+' in lvd['+str(i)+']' for i in range(npag)])+']' + s = '[['+','.join(['x'+str(i) for i in range(npag)])+'] ' + s += ' '.join(['for x'+str(i)+' in lvd['+str(i)+']' for i in range(npag)])+']' try: - lnup=eval(s) + lnup = eval(s) except SyntaxError, s: UTMESS('F','Table','Erreur lors de la construction des n-uplets') # pour chaque n-uplet, on imprime la sous-table for nup in lnup: - tab=self + tab = self for i in range(npag): tab = tab & (getattr(tab,ppag[i]) == nup[i]) - sl='' + sl = '' if tab.titr: sl='\n' tab.titr += sl+ppag[i]+': '+str(nup[i]) tab[lkeep].Impr(**kargs) @@ -147,7 +170,8 @@ class TableBase(object): if kargs.get('FICHIER')<>None: f.close() - def ReprTable(self,FORMAT='TABLEAU',dform=DicForm,**ignore): +# ------------------------------------------------------------------------------ + def ReprTable(self,FORMAT='TABLEAU',dform=None,**ignore): """Représentation d'une Table ou d'une Colonne sous forme d'un tableau. """ rows=self.rows @@ -156,6 +180,8 @@ class TableBase(object): if not type(para) in EnumTypes: para=[self.para,] typ =[self.type,] + if dform==None: + dform = DicForm.copy() # est-ce que l'attribut .type est renseigné ? typdef=typ<>[None]*len(typ) txt=[] @@ -172,9 +198,9 @@ class TableBase(object): if typdef: stype=dform['csep'].join([''] + \ [FMT(dform,'formK',typ[i],lmax[i]) % typ[i] for i in range(len(para))]) - txt.append('') - txt.append('-'*80) - txt.append('') + txt.append(dform['ccom']) + txt.append(dform['ccom']+'-'*80) + txt.append(dform['ccom']) ASTER=(FORMAT=='ASTER') if ASTER: txt.append('#DEBUT_TABLE') @@ -182,7 +208,7 @@ class TableBase(object): if ASTER: txt.extend(['#TITRE '+lig for lig in self.titr.split('\n')]) else: - txt.append(self.titr) + txt.extend([dform['ccom']+lig for lig in self.titr.split('\n')]) txt.append(dform['csep'].join(lspa)) if ASTER and typdef: txt.append(stype) @@ -196,7 +222,7 @@ class TableBase(object): if type(rep) is FloatType: lig.append(FMT(dform,'formR',t,lmax[i]) % rep) empty=False - elif type(rep) is IntType: + elif type(rep) in (IntType, LongType): lig.append(FMT(dform,'formI',t,lmax[i]) % rep) empty=False else: @@ -210,9 +236,14 @@ class TableBase(object): s='\\'+s lig.append(s) if not empty: - txt.append(dform['csep'].join(lig)) + lig2 = [dform['sepch'].join(ch.splitlines()) for ch in lig] + txt.append(dform['csep'].join(lig2)) if ASTER: txt.append('#FIN_TABLE') + # ajout du debut de ligne + if dform['cdeb']<>'': + txt=[dform['cdeb']+t for t in txt] + return dform['cfin'].join(txt) # ------------------------------------------------------------------------------ def ImprTabCroise(self,**kargs): @@ -223,19 +254,23 @@ class TableBase(object): kargs['FORMAT']='TABLEAU' tabc.Impr(**kargs) # ------------------------------------------------------------------------------ - def ImprGraph(self,**kargs): + def ImprGraph(self, **kargs): """Impression au format XMGRACE : via le module Graph """ args=kargs.copy() - if len(self.para)<>2: - UTMESS('A','Table','La table doit avoir exactement deux paramètres.') + if len(self.para) != 2: + UTMESS('A','Table','La table doit avoir exactement deux paramètres '\ + 'pour une impression au format XMGRACE.') return - lx, ly = [[v for v in getattr(self,p).values() if v<>None] for p in self.para] + # suppression des lignes contenant une cellule vide + tnv = getattr(self, self.para[0]).NON_VIDE() \ + & getattr(self, self.para[1]).NON_VIDE() # objet Graph graph=Graph.Graph() dicC={ - 'Val' : [lx, ly], - 'Lab' : self.para, + 'Val' : [getattr(tnv, tnv.para[0]).values(), + getattr(tnv, tnv.para[1]).values()], + 'Lab' : tnv.para, } if args['LEGENDE']==None: del args['LEGENDE'] Graph.AjoutParaCourbe(dicC, args) @@ -285,6 +320,7 @@ class Table(TableBase): t.a retourne un objet intermédiaire de la classe Colonne qui mémorise le nom de la colonne demandée (a, ici). """ +# ------------------------------------------------------------------------------ def __init__(self, rows=[], para=[], typ=[], titr=''): """Constructeur de la Table : rows : liste des lignes (dict) @@ -292,22 +328,124 @@ class Table(TableBase): type : liste des types des paramètres titr : titre de la table """ - self.rows=[r for r in rows if r.values()<>[None]*len(r.values())] - self.para=list(para) - if len(typ)==len(self.para): - self.type=list(typ) + self.rows = [r for r in rows if r.values() != [None]*len(r.values())] + self.para = list(para) + for i in self.para : + if self.para.count(i) != 1 : + UTMESS('F','Table','Parametre en double: %s' %i) + if len(typ) == len(self.para): + self.type = list(typ) else: - self.type=[None]*len(self.para) - self.titr=titr + self.type = [None]*len(self.para) + self.titr = titr + +# ------------------------------------------------------------------------------ + def copy(self): + """Retourne une copie de la table. + """ + rows = [] + for r in self.rows: + rows.append(copy(r)) + return Table(rows, self.para[:], self.type[:], self.titr) +# ------------------------------------------------------------------------------ def append(self, obj): - """Ajoute une ligne (type dict) à la Table""" + """Ajoute une ligne (type dict) qui peut éventuellement définir un + nouveau paramètre.""" + para=obj.keys() + for p in para: + if not p in self.para: + self.para.append(p) + self.type.append(_typaster(obj[p])) + else: + ip=self.para.index(p) + self.type[ip]=_typaster(obj[p], self.type[ip]) self.rows.append(obj) +# ------------------------------------------------------------------------------ + def SansColonneVide(self): + """Retourne une copie de la table dans laquelle on a supprimé les colonnes + vides (les lignes vides sont automatiquement supprimées). + """ + tab = self.copy() + lp = tab.para[:] + for para in lp: + if len(tab[para]) == 0: + bid = lp.pop(0) + return tab[lp] + +# ------------------------------------------------------------------------------ + def __setitem__(self, k_para, k_value): + """Ajoute une colonne k_para dont les valeurs sont dans k_value""" + if len(k_value)==0: + return + if k_para in self.para : + UTMESS('F','Table','(setitem) Le parametre %s existe déjà.' % k_para) + self.para.append(k_para) + self.type.append(_typaster(k_value[0])) + i=0 + for row in self: + if ilen(keys): -# order=[order[0],] -# else: -# # si toutes les valeurs sont identiques, on peut ne garder que la 1ère -# d={} -# for o in order: d[o]=None -# if len(order)<>len(keys) or len(d.keys())==1: -# order=[order[0],] -# if len(order)==1: -# self.rows=sort_table(self.rows, self.para, keys, (order[0]=='DECROISSANT')) -# else: -# # de la dernière clé à la première -# for k,o in [(keys[i],order[i]) for i in range(len(keys)-1,-1,-1)]: -# print 'TRI : clé=%s, order=%s' % (k,o) -# self.rows=sort_table(self.rows, self.para, [k], (o=='DECROISSANT')) + CLES = list(CLES) + not_found = ', '.join([p for p in CLES if not p in self.para]) + if not_found != '': + UTMESS('F', 'Table', 'Parametre(s) absent(s) de la table : %s' % not_found) + if not ORDRE in ('CROISSANT', 'DECROISSANT'): + UTMESS('F', 'Table', 'Valeur incorrecte pour ORDRE : %s' % ORDRE) + # tri + self.rows = sort_table(self.rows, self.para, CLES, (ORDRE=='DECROISSANT')) +# ------------------------------------------------------------------------------ def __delitem__(self, args): """Supprime les colonnes correspondantes aux éléments de args """ if not type(args) in EnumTypes: @@ -360,16 +488,17 @@ class Table(TableBase): for item in args: del new_type[new_para.index(item)] new_para.remove(item) - for line in new_rows : del line[item] + for line in new_rows: + del line[item] return Table(new_rows, new_para, new_type, self.titr) +# ------------------------------------------------------------------------------ def __getitem__(self, args): """Extrait la sous table composée des colonnes dont les paramètres sont dans args """ if not type(args) in EnumTypes: args=[args,] else: args=list(args) - #print ' args=',args new_rows=[] new_para=args new_type=[] @@ -384,6 +513,7 @@ class Table(TableBase): new_rows.append(new_line) return Table(new_rows, new_para, new_type, self.titr) +# ------------------------------------------------------------------------------ def __and__(self, other): """Intersection de deux tables (opérateur &)""" if other.para<>self.para: @@ -393,6 +523,7 @@ class Table(TableBase): tmp = [ r for r in self if r in other.rows ] return Table(tmp, self.para, self.type, self.titr) +# ------------------------------------------------------------------------------ def __or__(self, other): """Union de deux tables (opérateur |)""" if other.para<>self.para: @@ -403,6 +534,7 @@ class Table(TableBase): tmp.extend([ r for r in other if r not in self ]) return Table(tmp, self.para, self.type[:], self.titr) +# ------------------------------------------------------------------------------ def values(self): """Renvoie la table sous la forme d'un dictionnaire de listes dont les clés sont les paramètres. @@ -412,25 +544,67 @@ class Table(TableBase): dico[column]=Colonne(self, column).values() return dico +# ------------------------------------------------------------------------------ + def dict_CREA_TABLE(self): + """Renvoie le dictionnaire des mots-clés à fournir à la commande CREA_TABLE + pour produire une table_sdaster. + """ + dico={ 'TITRE' : ['%-80s' % lig for lig in self.titr.split('\n')], + 'LISTE' : [], } + # remplissage de chaque occurence (pour chaque paramètre) du mot-clé facteur LISTE + for i in range(len(self.para)): + # nom du paramètre et type si K* + d={ 'PARA' : self.para[i], } + typ=self.type[i] + if typ==None: + UTMESS('F', 'Table', 'Type du paramètre %s non défini.' %\ + self.para[i]) + elif typ[0]=='K': + mc='LISTE_K' + if not typ in ('K8', 'K16', 'K24'): + UTMESS('A','Table','Type du paramètre %s forcé à %s' % (self.para[i],Kdef)) + typ=Kdef + d['TYPE_K']=typ + elif typ=='I': + mc='LISTE_I' + elif typ=='R': + mc='LISTE_R' + # valeurs sans trou / avec trou + vals=getattr(self, self.para[i]).values() + if vals.count(None)==0: + d[mc]=vals + else: + d['NUME_LIGN'] = [j+1 for j in range(len(vals)) if vals[j]<>None] + d[mc] = [v for v in vals if v <>None] + if len(d[mc])==0: + UTMESS('I','Table','Colonne %s vide' % self.para[i]) + else: + dico['LISTE'].append(d) + if len(dico['LISTE'])==0: + UTMESS('F','Table','La table est vide') + return dico + +# ------------------------------------------------------------------------------ def Array(self,Para,Champ): """Renvoie sous forme de NumArray le résultat d'une extraction dans une table méthode utile à macr_recal """ import Numeric __Rep = self[Para,Champ].values() - F=Numeric.zeros((len(__Rep[Para]),2),Numeric.Float) + F = Numeric.zeros((len(__Rep[Para]),2), Numeric.Float) for i in range(len(__Rep[Para])): - F[i][0] = __Rep[Para][i] - F[i][1] = __Rep[Champ][i] + F[i][0] = __Rep[Para][i] + F[i][1] = __Rep[Champ][i] del(__Rep) return F +# ------------------------------------------------------------------------------ def Croise(self): """Retourne un tableau croisé P3(P1,P2) à partir d'une table ayant trois paramètres (P1, P2, P3). """ if len(self.para)<>3: - UTMESS('A','Table','La table doit avoir exactement trois paramètres.') + UTMESS('A', 'Table', 'La table doit avoir exactement trois paramètres.') return Table() py, px, pz = self.para ly, lx, lz = [getattr(self,p).values() for p in self.para] @@ -459,6 +633,20 @@ class Table(TableBase): new_titr+=pz + ' FONCTION DE ' + px + ' ET ' + py return Table(new_rows, new_para, new_type, new_titr) +# ------------------------------------------------------------------------------ + def Renomme(self, pold, pnew): + """Renomme le paramètre `pold` en `pnew`. + """ + if not pold in self.para: + raise KeyError, 'Paramètre %s inexistant dans cette table' % pold + elif self.para.count(pnew)>0: + raise KeyError, 'Le paramètre %s existe déjà dans la table' % pnew + else: + self.para[self.para.index(pold)] = pnew + for lig in self: + lig[pnew] = lig[pold] + del lig[pold] + # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------ @@ -469,13 +657,14 @@ class Colonne(TableBase): Alors on peut écrire la requete simple : soustable=t.a<10 Ainsi que des requetes plus complexes : - soustable=t.a<10 & t.b <4 + soustable=t.a<10 and t.b <4 ou - soustable=t.a<10 | t.b <4 + soustable=t.a<10 or t.b <4 Les "alias" EQ, NE, LE, LT, GE, GT permettent à la macro IMPR_TABLE d'utiliser directement le mot-clé utilisateur CRIT_COMP défini dans le catalogue : getattr(Table,CRIT_COMP). """ +# ------------------------------------------------------------------------------ def __init__(self, table, column, typ=None): """Constructeur (objet Table associé, paramètre de la colonne, type du paramètre). @@ -486,6 +675,7 @@ class Colonne(TableBase): self.type=typ self.titr='' +# ------------------------------------------------------------------------------ def _extract(self, fun): """Construit une table avec les lignes de self.Table dont l'élément de nom self.para satisfait le critère fun, @@ -493,18 +683,23 @@ class Colonne(TableBase): """ return Table([row for row in self.Table if fun(row.get(self.para))], self.Table.para, self.Table.type, self.Table.titr) +# ------------------------------------------------------------------------------ def __le__(self, VALE): return self._extract(lambda v: v<>None and v<=VALE) +# ------------------------------------------------------------------------------ def __lt__(self, VALE): return self._extract(lambda v: v<>None and vNone and v>=VALE) +# ------------------------------------------------------------------------------ def __gt__(self, VALE): return self._extract(lambda v: v<>None and v>VALE) +# ------------------------------------------------------------------------------ def __eq__(self, VALE, CRITERE='RELATIF', PRECISION=0.): if type(VALE) in EnumTypes : return self._extract(lambda v: v in VALE) @@ -522,6 +717,16 @@ class Colonne(TableBase): vmax=(1.+PRECISION)*VALE return self._extract(lambda v: v<>None and vminNone and (vs',dform['form'+typAster]) - #print nform, typAster, fmt else: fmt=dform[nform] else: @@ -647,76 +871,96 @@ def FMT(dform, nform, typAster=None, larg=0, val=''): return fmt # ------------------------------------------------------------------------------ +def merge(tab1, tab2, labels=[]): + """Assemble les deux tables tb1 et tb2 selon une liste de labels communs. + Si labels est vide: + - les lignes de tb2 sont ajoutés à celles de tb1, + sinon : + - si on trouve les valeurs de tb2 sur les labels dans tb1 (et une seule fois), + on surcharge tb1 avec les lignes de tb2 ; + - sinon on ajoute la ligne de tb2 à la fin de tb1. + """ + tb1 = tab1.copy() + tb2 = tab2.copy() + if type(labels) not in EnumTypes: + labels=(labels,) + for key in labels : + if key not in tb1.para : UTMESS('F','Table','Erreur, label non présent %s' % key) + if key not in tb2.para : UTMESS('F','Table','Erreur, label non présent %s' % key) + # ensemble des paramètres et des types + n_para=tb1.para[:] + n_type=tb1.type[:] + for i in tb2.para: + if i not in tb1.para: + n_para.append(i) + n_type.append(tb2.type[tb2.para.index(i)]) + # restriction des lignes aux labels communs (peu cher en cpu) + rows1 = tb1.rows + dlab1 = {} + for i1 in range(len(rows1)): + tu1 = tuple(map(rows1[i1].__getitem__, labels)) + if dlab1.get(tu1, '') == '': + dlab1[tu1] = i1 + else: + dlab1[tu1] = None + # restriction des lignes aux labels communs (peu cher en cpu) + rows2 = tb2.rows + dlab2 = {} + for i2 in range(len(rows2)): + tu2 = tuple(map(rows2[i2].__getitem__, labels)) + if dlab2.get(tu2, '') == '': + dlab2[tu2] = i2 + else: + dlab2[tu2] = None + # creation de dic1 : dictionnaire de correspondance entre les + # lignes a merger dans les deux tableaux + dic1 = {} + for cle in dlab1.keys(): + if dlab1[cle] == None or cle == (): + bid = dlab1.pop(cle) + for cle in dlab2.keys(): + if dlab2[cle] == None or cle == (): + bid = dlab2.pop(cle) + for cle in dlab2.keys(): + if dlab1.has_key(cle): + dic1[dlab2[cle]] = dlab1[cle] + # insertion des valeurs de tb2 dans tb1 quand les labels sont communs + # (et uniques dans chaque table) OU ajout de la ligne de tb2 dans tb1 + i2 = -1 + for r2 in rows2: + i2 += 1 + try: + rows1[dic1[i2]].update(r2) + except KeyError: + rows1.append(r2) + # concaténation des titres + info sur le merge + tit = '\n'.join([tb1.titr, tb2.titr, 'MERGE avec labels=%s' % repr(labels)]) + return Table(rows1, n_para, n_type, tit) + # ------------------------------------------------------------------------------ -# ------------------------------------------------------------------------------ -if __name__ == "__main__": - listdic = [ - {'NOEUD': 'N1' ,'NUME_ORDRE': 1 ,'INST': 0.5, 'DX': -0.00233, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N1' ,'NUME_ORDRE': 2 ,'INST': 1.0, 'DX': -0.00467, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N1' ,'NUME_ORDRE': 3 ,'INST': 1.5, 'DX': -0.00701, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N1' ,'NUME_ORDRE': 4 ,'INST': 2.0, 'DX': -0.00934, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N1' ,'NUME_ORDRE': 5 ,'INST': 2.5, 'DX': -0.01168, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N2' ,'NUME_ORDRE': 11,'INST': 5.5, 'DX': -0.00233, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N2' ,'NUME_ORDRE': 12,'INST': 6.0, 'DX': -0.00467, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N2' ,'NUME_ORDRE': 13,'INST': 6.5, 'DX': -0.00701, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N2' ,'NUME_ORDRE': 14,'INST': 7.0, 'DX': -0.00934, 'COOR_Y': 0.53033,}, - {'NOEUD': 'N2' ,'NUME_ORDRE': 15,'INST': 7.5, 'DX': -0.01168, 'COOR_Y': 0.53033,}, - ] - import random - random.shuffle(listdic) - listpara=['NOEUD','NUME_ORDRE','INST','COOR_Y','DX'] - listtype=['K8','I','R','R','R'] - t=Table(listdic,listpara,listtype) - - tb=t[('NOEUD','DX')] - print tb.para - print tb.type - - print - print "------Table initiale----" - print t - print - print "--------- CRIT --------" - print t.NUME_ORDRE <=5 - print - print "------- CRIT & CRIT -----" - print (t.NUME_ORDRE < 10) & (t.INST >=1.5) - print - print "----- EQ maxi / min(col), max(col) ------" - print t.DX == max(t.DX) - print min(t.DX) - print max(t.DX) - print "------ getitem sur 2 paramètres ------" - print t.NUME_ORDRE - print t.DX - print t['DX','NUME_ORDRE'] - print "------ sort sur INST ------" - t.sort('INST') - print t - - print "------- TABLEAU_CROISE ------" - tabc=t['NOEUD','INST','DX'] - tabc.Impr(FORMAT='TABLEAU_CROISE') - - N=5 - ldic=[] - for i in range(N): - ldic.append({'IND':float(i), 'VAL' : random.random()*i}) - para=['IND','VAL'] - t3=Table(ldic, para, titr='Table aléatoire') - col=t3.VAL.ABS_MAXI() - col=t3.VAL.MINI() - - t3.sort('VAL','IND') - - tg=tabc['INST','DX'].DX.NON_VIDE() - #tg.Impr(FORMAT='XMGRACE') - - g=Graph.Graph() - g.Titre="Tracé d'une fonction au format TABLEAU" - g.AjoutCourbe(Val=[tg.INST.values(), tg.DX.values()], Lab=['INST','DX']) - g.Trace(FORMAT='TABLEAU') - -# t.Impr(PAGINATION='NOEUD') - t.Impr(PAGINATION=('NOEUD','INST')) - +def _typaster(obj, prev=None, strict=False): + """Retourne le type Aster ('R', 'I', Kdef) correspondant à l'objet obj. + Si prev est fourni, on vérifie que obj est du type prev. + Si strict=False, on autorise que obj ne soit pas du type prev s'ils sont + tous les deux numériques ; dans ce cas, on retourne le "type enveloppe" 'R'. + """ + dtyp={ + IntType : 'I', + FloatType : 'R', + StringType : Kdef, UnicodeType : Kdef, + NoneType : 'I', + } + if type(obj) in dtyp.keys(): + typobj=dtyp[type(obj)] + if prev in [None, typobj]: + return typobj + elif strict: # prev<>None et typobj<>prev et strict + raise TypeError, "La valeur %s n'est pas de type %s" % (repr(obj),repr(prev)) + elif prev in ('I','R') and typobj in ('I','R'): + return 'R' + else: + raise TypeError, "La valeur %s n'est pas compatible avec le type %s" \ + % (repr(obj),repr(prev)) + else: + raise TypeError, 'Une table ne peut contenir que des entiers, réels ' \ + 'ou chaines de caractères.' diff --git a/Aster/Cata/Utilitai/UniteAster.py b/Aster/Cata/Utilitai/UniteAster.py index 141b3249..54e2adc4 100644 --- a/Aster/Cata/Utilitai/UniteAster.py +++ b/Aster/Cata/Utilitai/UniteAster.py @@ -1,4 +1,4 @@ -#@ MODIF UniteAster Utilitai DATE 11/05/2005 AUTEUR MCOURTOI M.COURTOIS +#@ MODIF UniteAster Utilitai DATE 29/08/2006 AUTEUR MCOURTOI M.COURTOIS # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -84,16 +84,17 @@ class UniteAster: print __tab.EXTR_TABLE() raise aster.FatalError," %s" % message self.infos[unit]['nom'] = nomfich - DETRUIRE(CONCEPT=_F(NOM=__tab)) + #print 'DEBUG infos[unit] = ', self.infos[unit] + DETRUIRE(CONCEPT=_F(NOM=__tab),INFO=1) #------------------------------------------------------------------------------- - def Libre(self, nom=None): - """Réserve et retourne une unité libre en y associant, s'il est fourni, - le fichier 'nom'. + def Libre(self, nom=None, action='RESERVER'): + """Réserve/associe et retourne une unité libre en y associant, s'il est + fourni, le fichier 'nom'. """ __tab=INFO_EXEC_ASTER(LISTE_INFO=('UNITE_LIBRE')) unit = __tab['UNITE_LIBRE',1] - DETRUIRE(CONCEPT=_F(NOM=__tab)) + DETRUIRE(CONCEPT=_F(NOM=__tab),INFO=1) if nom==None: nom='fort.'+str(unit) @@ -103,7 +104,7 @@ class UniteAster: self.infos[unit]['nom'] raise aster.FatalError," %s" % message - DEFI_FICHIER(ACTION='RESERVER', UNITE=unit , FICHIER=nom.strip()) + DEFI_FICHIER(ACTION=action, UNITE=unit , FICHIER=nom.strip()) self.infos[unit] = {} self.infos[unit]['nom'] = nom.strip() self.infos[unit]['etat'] = 'R' @@ -129,8 +130,9 @@ class UniteAster: """Retourne l'état de l'unité si 'etat' n'est pas fourni et/ou change son état : kargs['etat'] : nouvel état, + kargs['nom'] : nom du fichier, kargs['TYPE'] : type du fichier à ouvrir ASCII/BINARY/LIBRE, - kargs['ACCES'] : type d'accès NEW/APPEND/OLD. + kargs['ACCES'] : type d'accès NEW/APPEND/OLD (APPEND uniquement en ASCII). """ # ul peut etre un entier Aster try: @@ -156,17 +158,26 @@ class UniteAster: DEFI_FICHIER(ACTION='LIBERER', UNITE=unit) DEFI_FICHIER(ACTION = 'RESERVER', UNITE = unit, - FICHIER = self.infos[unit]['nom']) + FICHIER = kargs.get('nom', self.infos[unit]['nom'])) + self._setinfo(unit) elif new == 'F': DEFI_FICHIER(ACTION='LIBERER', UNITE=unit) elif new == 'O': if self.infos[unit]['etat'] == 'R': DEFI_FICHIER(ACTION='LIBERER', UNITE=unit) + # valeurs par défaut + typ = kargs.get('TYPE', 'ASCII') + if typ == 'ASCII': + acces = 'APPEND' + else: + acces = 'OLD' + acces = kargs.get('ACCES', acces) DEFI_FICHIER(ACTION ='ASSOCIER', UNITE = unit, - FICHIER = self.infos[unit]['nom'], - TYPE = kargs.get('TYPE', 'ASCII'), - ACCES = kargs.get('ACCES', 'APPEND'),) + FICHIER = kargs.get('nom', self.infos[unit]['nom']), + TYPE = typ, + ACCES = acces,) + self._setinfo(unit) self.infos[unit]['etat'] = new return self.infos[unit]['etat'] diff --git a/Aster/Cata/Utilitai/Utmess.py b/Aster/Cata/Utilitai/Utmess.py index 1659f9ef..11810168 100644 --- a/Aster/Cata/Utilitai/Utmess.py +++ b/Aster/Cata/Utilitai/Utmess.py @@ -1,4 +1,4 @@ -#@ MODIF Utmess Utilitai DATE 30/11/2004 AUTEUR MCOURTOI M.COURTOIS +#@ MODIF Utmess Utilitai DATE 17/10/2005 AUTEUR MCOURTOI M.COURTOIS # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -23,42 +23,27 @@ import aster def UTMESS(code, sprg, texte): """Utilitaire analogue à la routine fortran UTMESS. - code : 'A', 'E', 'S', 'F' + code : 'A', 'E', 'S', 'F', 'I' sprg : nom du module, classe ou fonction python où l'on se trouve texte : contenu du message """ fmt='\n <%s> <%s> %s\n\n' - UL={ - 'MESSAGE' : 6, - 'RESULTAT' : 8, - #'ERREUR' : 9, - } - # On importe la définition des commandes à utiliser dans la macro -# if jdc: -# DEFI_FICHIER = jdc.get_cmd('DEFI_FICHIER') -# else: -# # on se limite au print ! -# UL={ 'MESSAGE' : 6, } - try: - from Cata.cata import DEFI_FICHIER - except ImportError: - # on se limite au print ! - UL={ 'MESSAGE' : 6, } - - reason=fmt % (code, sprg, texte) + sanscode='\n <%s> %s\n\n' + UL=[ + 'MESSAGE', + 'RESULTAT', + #'ERREUR', + ] +# + # Comme l'UTMESS fortran, on supprime le code si on ne fait pas l'abort + if aster.onFatalError()=='EXCEPTION': + reason=sanscode % (sprg, texte) + else: + reason=fmt % (code, sprg, texte) - for nom,ul in UL.items(): - if ul<>6: - DEFI_FICHIER(ACTION='LIBERER', UNITE=ul, ) - f=open('fort.'+str(ul),'a') - else: - f=sys.stdout + for nom in UL: # écriture du message - f.write(reason) - - if ul<>6: - f.close() - DEFI_FICHIER(ACTION='ASSOCIER', UNITE=ul, TYPE='ASCII', ACCES='APPEND') + aster.affiche(nom,reason) if code=='S': raise aster.error, reason diff --git a/Aster/Cata/Utilitai/sup_gmsh.py b/Aster/Cata/Utilitai/sup_gmsh.py index a173ab11..94e323ce 100644 --- a/Aster/Cata/Utilitai/sup_gmsh.py +++ b/Aster/Cata/Utilitai/sup_gmsh.py @@ -1,4 +1,4 @@ -#@ MODIF sup_gmsh Utilitai DATE 10/05/2005 AUTEUR GJBHHEL E.LORENTZ +#@ MODIF sup_gmsh Utilitai DATE 08/11/2005 AUTEUR ASSIRE A.ASSIRE # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -1320,8 +1320,9 @@ class Mesh : def Create(self, file = 'fort.19') : self.Save() -# os.system('gmsh -3 fort.geo') os.system(self.gmsh + ' -3 fort.geo') + try: os.remove(file) + except: pass os.rename('fort.msh',file) diff --git a/Aster/Cata/Utilitai/t_fonction.py b/Aster/Cata/Utilitai/t_fonction.py index 0ead839c..ed6042b1 100644 --- a/Aster/Cata/Utilitai/t_fonction.py +++ b/Aster/Cata/Utilitai/t_fonction.py @@ -1,4 +1,4 @@ -#@ MODIF t_fonction Utilitai DATE 31/05/2005 AUTEUR DURAND C.DURAND +#@ MODIF t_fonction Utilitai DATE 25/09/2006 AUTEUR MCOURTOI M.COURTOIS # -*- coding: iso-8859-1 -*- # CONFIGURATION MANAGEMENT OF EDF VERSION # ====================================================================== @@ -20,8 +20,14 @@ from Numeric import * import copy import types +from sets import Set + +class FonctionError(Exception): + pass def interp(typ_i,val,x1,x2,y1,y2) : + """Interpolation linéaire/logarithmique entre un couple de valeurs + """ if typ_i==['LIN','LIN']: return y1+(y2-y1)*(val-x1)/(x2-x1) if typ_i==['LIN','LOG']: return exp(log(y1)+(val-x1)*(log(y2)-log(y1))/(x2-x1)) if typ_i==['LOG','LOG']: return exp(log(y1)+(log(val)-log(x1))*(log(y2)-log(y1))/(log(x2)-log(x1))) @@ -29,38 +35,41 @@ def interp(typ_i,val,x1,x2,y1,y2) : if typ_i[0]=='NON' : if val==x1 : return y1 elif val==x2 : return y2 - else : raise StandardError, 'fonction : interpolation NON' + else : raise FonctionError, 'fonction : interpolation NON' def is_ordo(liste) : - listb=dict([(i,0) for i in liste]).keys() + listb=list(Set(liste)) listb.sort() return liste==listb class t_fonction : - ### Classe pour fonctions réelles, équivalent au type aster = fonction_sdaster + """Classe pour fonctions réelles, équivalent au type aster = fonction_sdaster + """ def __init__(self,vale_x,vale_y,para) : - # création d'un objet fonction - # vale_x et vale_y sont des listes de réels de meme longueur - # para est un dictionnaire contenant les entrées PROL_DROITE, PROL_GAUCHE et INTERPOL (cf sd ASTER) + """Création d'un objet fonction + - vale_x et vale_y sont des listes de réels de meme longueur + - para est un dictionnaire contenant les entrées PROL_DROITE, PROL_GAUCHE et INTERPOL (cf sd ASTER) + """ pk=para.keys() pk.sort() if pk!=['INTERPOL','NOM_PARA','NOM_RESU','PROL_DROITE','PROL_GAUCHE'] : - raise StandardError, 'fonction : parametres incorrects' + raise FonctionError, 'fonction : parametres incorrects' if para['INTERPOL'] not in [['NON','NON'],['LIN','LIN'],['LIN','LOG'],['LOG','LOG'],['LOG','LIN'],] : - raise StandardError, 'fonction : parametre INTERPOL incorrect' + raise FonctionError, 'fonction : parametre INTERPOL incorrect' if para['PROL_DROITE'] not in ['EXCLU','CONSTANT','LINEAIRE'] : - raise StandardError, 'fonction : parametre PROL_DROITE incorrect' + raise FonctionError, 'fonction : parametre PROL_DROITE incorrect' if para['PROL_GAUCHE'] not in ['EXCLU','CONSTANT','LINEAIRE'] : - raise StandardError, 'fonction : parametre PROL_GAUCHE incorrect' + raise FonctionError, 'fonction : parametre PROL_GAUCHE incorrect' self.vale_x = array(vale_x) self.vale_y = array(vale_y) self.para = para if len(self.vale_x)!=len(self.vale_y) : - raise StandardError, 'fonction : longueur abscisse <> longueur ordonnées' + raise FonctionError, 'fonction : longueur abscisse <> longueur ordonnées' if not is_ordo(self.vale_x) : - raise StandardError, 'fonction : abscisses non strictement croissantes' + raise FonctionError, 'fonction : abscisses non strictement croissantes' def __add__(self,other) : - # addition avec une autre fonction ou un nombre, par surcharge de l'opérateur + + """addition avec une autre fonction ou un nombre, par surcharge de l'opérateur + + """ if isinstance(other,t_fonction): para=copy.copy(self.para) vale_x,para['PROL_GAUCHE'],para['PROL_DROITE']=self.homo_support(other) @@ -71,10 +80,11 @@ class t_fonction : elif type(other) in [types.FloatType,types.IntType,types.ComplexType] : if isinstance(self,t_fonction_c): return t_fonction_c(self.vale_x,self.vale_y+other,self.para) else : return t_fonction(self.vale_x,self.vale_y+other,self.para) - else: raise StandardError, 'fonctions : erreur de type dans __add__' + else: raise FonctionError, 'fonctions : erreur de type dans __add__' def __mul__(self,other) : - # multiplication avec une autre fonction ou un nombre, par surcharge de l'opérateur * + """multiplication avec une autre fonction ou un nombre, par surcharge de l'opérateur * + """ if isinstance(other,t_fonction): para=copy.copy(self.para) vale_x,para['PROL_GAUCHE'],para['PROL_DROITE']=self.homo_support(other) @@ -86,34 +96,37 @@ class t_fonction : return t_fonction(self.vale_x,self.vale_y*other,self.para) elif type(other) ==types.ComplexType : return t_fonction_c(self.vale_x,self.vale_y*other,self.para) - else: raise StandardError, 'fonctions : erreur de type dans __mul__' + else: raise FonctionError, 'fonctions : erreur de type dans __mul__' def __repr__(self) : - # affichage de la fonction en double colonne + """affichage de la fonction en double colonne + """ texte=[] for i in range(len(self.vale_x)) : texte.append('%f %f' % (self.vale_x[i],self.vale_y[i])) return '\n'.join(texte) def __getitem__(self,other) : - # composition de deux fonction F[G]=FoG=F(G(x)) + """composition de deux fonction F[G]=FoG=F(G(x)) + """ para=copy.copy(self.para) if other.para['NOM_RESU']!=self.para['NOM_PARA'] : - raise StandardError,'''composition de fonctions : NOM_RESU1 et NOM_PARA2 incohérents ''' + raise FonctionError,'''composition de fonctions : NOM_RESU1 et NOM_PARA2 incohérents ''' para['NOM_PARA']==other.para['NOM_PARA'] return t_fonction(other.vale_x,map(self,other.vale_y),para) def __call__(self,val,tol=1.e-6): - # méthode pour évaluer f(x) - # tolérance, par défaut 1.e-6 en relatif sur la longueur de l'intervalle - # adjacent, pour capter les erreurs d'arrondi en cas de prolongement exclu + """méthode pour évaluer f(x) + - tolérance, par défaut 1.e-6 en relatif sur la longueur de l'intervalle + - adjacent, pour capter les erreurs d'arrondi en cas de prolongement exclu + """ i=searchsorted(self.vale_x,val) n=len(self.vale_x) if i==0 : if self.para['PROL_GAUCHE']=='EXCLU' : eps_g=(val-self.vale_x[0] )/(self.vale_x[1] -self.vale_x[0]) if abs(eps_g)<=tol : return self.vale_y[0] - else : raise StandardError, 'fonction évaluée hors du domaine de définition' + else : raise FonctionError, 'fonction évaluée hors du domaine de définition' else : if self.para['PROL_GAUCHE']=='CONSTANT' : return self.vale_y[0] if self.para['PROL_GAUCHE']=='LINEAIRE' : return interp(self.para['INTERPOL'],val,self.vale_x[0], @@ -124,7 +137,7 @@ class t_fonction : if self.para['PROL_DROITE']=='EXCLU' : eps_d=(val-self.vale_x[-1])/(self.vale_x[-1]-self.vale_x[-2]) if abs(eps_d)<=tol : return self.vale_y[-1] - else : raise StandardError, 'fonction évaluée hors du domaine de définition' + else : raise FonctionError, 'fonction évaluée hors du domaine de définition' else : if self.para['PROL_DROITE']=='CONSTANT' : return self.vale_y[-1] if self.para['PROL_DROITE']=='LINEAIRE' : return interp(self.para['INTERPOL'],val,self.vale_x[-1], @@ -138,11 +151,12 @@ class t_fonction : self.vale_y[i]) def homo_support(self,other) : - # renvoie le support d'abscisses homogénéisé entre self et other - # i.e. si prolongement exclu, on retient plus grand min ou plus petit max, selon - # si prolongement autorisé, on conserve les abscisses d'une fonction, extrapolantes - # sur l'autre. - # Pour les points intermédiaires : union et tri des valeurs des vale_x réunis. + """Renvoie le support d'abscisses homogénéisé entre self et other + i.e. si prolongement exclu, on retient plus grand min ou plus petit max, selon + si prolongement autorisé, on conserve les abscisses d'une fonction, extrapolantes + sur l'autre. + Pour les points intermédiaires : union et tri des valeurs des vale_x réunis. + """ if other.vale_x[0]>self.vale_x[0]: if other.para['PROL_GAUCHE']!='EXCLU' : f_g=self else : f_g=other @@ -165,18 +179,19 @@ class t_fonction : return vale_x,prol_gauche,prol_droite def cut(self,rinf,rsup,prec,crit='RELATIF') : - # renvoie la fonction self dont on a 'coupé' les extrémités en x=rinf et x=rsup - # pour la recherche de rinf et rsup dans la liste d'abscisses : - # prec=precision crit='absolu' ou 'relatif' + """Renvoie la fonction self dont on a 'coupé' les extrémités en x=rinf et x=rsup + pour la recherche de rinf et rsup dans la liste d'abscisses : + prec=precision crit='absolu' ou 'relatif' + """ para=copy.copy(self.para) para['PROL_GAUCHE']='EXCLU' para['PROL_DROITE']='EXCLU' if crit=='ABSOLU' : rinf_tab=greater(abs(self.vale_x-rinf),prec) elif crit=='RELATIF': rinf_tab=greater(abs(self.vale_x-rinf),prec*rinf) - else : raise StandardError, 'fonction : cut : critère absolu ou relatif' + else : raise FonctionError, 'fonction : cut : critère absolu ou relatif' if crit=='ABSOLU' : rsup_tab=greater(abs(self.vale_x-rsup),prec) elif crit=='RELATIF': rsup_tab=greater(abs(self.vale_x-rsup),prec*rsup) - else : raise StandardError, 'fonction : cut : critère absolu ou relatif' + else : raise FonctionError, 'fonction : cut : critère absolu ou relatif' if alltrue(rinf_tab) : i=searchsorted(self.vale_x,rinf) else : i=rinf_tab.tolist().index(0)+1 if alltrue(rsup_tab) : j=searchsorted(self.vale_x,rsup) @@ -186,9 +201,10 @@ class t_fonction : return t_fonction(vale_x,vale_y,para) def cat(self,other,surcharge) : - # renvoie une fonction concaténée avec une autre, avec règles de surcharge + """renvoie une fonction concaténée avec une autre, avec règles de surcharge + """ para=copy.copy(self.para) - if self.para['INTERPOL']!=other.para['INTERPOL'] : raise StandardError, 'concaténation de fonctions à interpolations différentes' + if self.para['INTERPOL']!=other.para['INTERPOL'] : raise FonctionError, 'concaténation de fonctions à interpolations différentes' if min(self.vale_x)1.e-2 : - raise StandardError, 'fonction réelle : FFT : la fonction doit etre à pas constant' + raise FonctionError, 'fonction réelle : FFT : la fonction doit etre à pas constant' n=int(log(len(self.vale_x))/log(2)) if methode=='TRONCATURE' : vale_y=self.vale_y[:2**n] @@ -391,31 +420,35 @@ class t_fonction : return t_fonction_c(vale_x,vale_y,para) class t_fonction_c(t_fonction) : - ### Classe pour fonctions complexes, équivalent au type aster = fonction_c + """Classe pour fonctions complexes, équivalent au type aster = fonction_c + """ def tabul(self) : - # mise en forme de la fonction selon un vecteur unique (x1,yr1,yi1,x2,yr2,yr2,...) + """mise en forme de la fonction selon un vecteur unique (x1,yr1,yi1,x2,yr2,yr2,...) + """ __tab=array([self.vale_x,self.vale_y.real,self.vale_y.imag]) return ravel(transpose(__tab)).tolist() def __repr__(self) : - # affichage de la fonction en double colonne + """affichage de la fonction en double colonne + """ texte=[] for i in range(len(self.vale_x)) : texte.append('%f %f + %f .j' % (self.vale_x[i],self.vale_y[i].real,self.vale_y[i].imag)) return '\n'.join(texte) def fft(self,methode,syme) : - # renvoie la transformée de Fourier rapide FFT (sens inverse) + """renvoie la transformée de Fourier rapide FFT (sens inverse) + """ import FFT para=copy.copy(self.para) para['NOM_PARA']='INST' if self.para['NOM_PARA']!='FREQ' : - raise StandardError, 'fonction complexe : FFT : NOM_PARA=FREQ pour une transformée directe' + raise FonctionError, 'fonction complexe : FFT : NOM_PARA=FREQ pour une transformée directe' pas = self.vale_x[1]-self.vale_x[0] for i in range(1,len(self.vale_x)) : ecart = abs(((self.vale_x[i]-self.vale_x[i-1])-pas)/pas) if ecart>1.e-3 : - raise StandardError, 'fonction complexe : FFT : la fonction doit etre à pas constant' + raise FonctionError, 'fonction complexe : FFT : la fonction doit etre à pas constant' n=int(log(len(self.vale_x))/log(2)) if syme=='OUI' and len(self.vale_x)==2**n : vale_fonc=self.vale_y @@ -439,7 +472,7 @@ class t_fonction_c(t_fonction) : vale_fonc=vale_fonc+vale_fon1 vale_fonc=array(vale_fonc) if syme=='OUI' and len(self.vale_x)!=2**n : - raise StandardError, 'fonction complexe : FFT : syme=OUI et nombre de points<>2**n' + raise FonctionError, 'fonction complexe : FFT : syme=OUI et nombre de points<>2**n' part1=vale_fonc[:len(vale_fonc)/2+1] part2=vale_fonc[1:len(vale_fonc)/2] part2=conjugate(part2) @@ -456,42 +489,45 @@ class t_fonction_c(t_fonction) : class t_nappe : - ### Classe pour nappes, équivalent au type aster = nappe_sdaster + """Classe pour nappes, équivalent au type aster = nappe_sdaster + """ def __init__(self,vale_para,l_fonc,para) : - # création d'un objet nappe - # vale_para est la liste de valeur des parametres (mot clé PARA dans DEFI_NAPPE) - # para est un dictionnaire contenant les entrées PROL_DROITE, PROL_GAUCHE et INTERPOL (cf sd ASTER) - # l_fonc est la liste des fonctions, de cardinal égal à celui de vale_para + """Création d'un objet nappe + - vale_para est la liste de valeur des parametres (mot clé PARA dans DEFI_NAPPE) + - para est un dictionnaire contenant les entrées PROL_DROITE, PROL_GAUCHE et INTERPOL (cf sd ASTER) + - l_fonc est la liste des fonctions, de cardinal égal à celui de vale_para + """ pk=para.keys() pk.sort() if pk!=['INTERPOL','NOM_PARA','NOM_PARA_FONC','NOM_RESU','PROL_DROITE','PROL_GAUCHE'] : - raise StandardError, 'nappe : parametres incorrects' + raise FonctionError, 'nappe : parametres incorrects' if para['INTERPOL'] not in [['NON','NON'],['LIN','LIN'], ['LIN','LOG'],['LOG','LOG'],['LOG','LIN'],] : - raise StandardError, 'nappe : parametre INTERPOL incorrect' + raise FonctionError, 'nappe : parametre INTERPOL incorrect' if para['PROL_DROITE'] not in ['EXCLU','CONSTANT','LINEAIRE'] : - raise StandardError, 'nappe : parametre PROL_DROITE incorrect' + raise FonctionError, 'nappe : parametre PROL_DROITE incorrect' if para['PROL_GAUCHE'] not in ['EXCLU','CONSTANT','LINEAIRE'] : - raise StandardError, 'nappe : parametre PROL_GAUCHE incorrect' + raise FonctionError, 'nappe : parametre PROL_GAUCHE incorrect' self.vale_para = array(vale_para) if type(l_fonc) not in (types.ListType,types.TupleType) : - raise StandardError, 'nappe : la liste de fonctions fournie n est pas une liste' + raise FonctionError, 'nappe : la liste de fonctions fournie n est pas une liste' if len(l_fonc)!=len(vale_para) : - raise StandardError, 'nappe : nombre de fonctions différent du nombre de valeurs du paramètre' + raise FonctionError, 'nappe : nombre de fonctions différent du nombre de valeurs du paramètre' for f in l_fonc : if not isinstance(f,t_fonction) and not isinstance(f,t_fonction_c) : - raise StandardError, 'nappe : les fonctions fournies ne sont pas du bon type' + raise FonctionError, 'nappe : les fonctions fournies ne sont pas du bon type' self.l_fonc = l_fonc self.para = para def __call__(self,val1,val2): - # méthode pour évaluer nappe(val1,val2) + """méthode pour évaluer nappe(val1,val2) + """ i=searchsorted(self.vale_para,val1) n=len(self.vale_para) if i==0 : if val1==self.vale_para[0] : return self.l_fonc[0](val2) if val1 self.vale_para[-1] : - if self.para['PROL_DROITE']=='EXCLU' : raise StandardError, 'nappe évaluée hors du domaine de définition' + if self.para['PROL_DROITE']=='EXCLU' : raise FonctionError, 'nappe évaluée hors du domaine de définition' if self.para['PROL_DROITE']=='CONSTANT' : return self.l_fonc[-1](val2) if self.para['PROL_DROITE']=='LINEAIRE' : return interp(self.para['INTERPOL'],val1, self.vale_para[-1], @@ -514,30 +550,43 @@ class t_nappe : self.l_fonc[i-1](val2), self.l_fonc[i](val2)) + def evalfonc(self, liste_val) : + """Renvoie la mm nappe dont les fonctions sont interpolées aux points définis + par la liste 'liste_val'. + """ + l_fonc = [] + for f in self.l_fonc: + f2 = f.evalfonc(liste_val) + l_fonc.append(f2) + return t_nappe(self.vale_para, l_fonc, self.para) + def __add__(self,other) : - # addition avec une autre nappe ou un nombre, par surcharge de l'opérateur + + """addition avec une autre nappe ou un nombre, par surcharge de l'opérateur + + """ l_fonc=[] if isinstance(other,t_nappe): - if self.vale_para!=other.vale_para : raise StandardError, 'nappes à valeurs de paramètres différentes' + if self.vale_para!=other.vale_para : raise FonctionError, 'nappes à valeurs de paramètres différentes' for i in range(len(self.l_fonc)) : l_fonc.append(self.l_fonc[i]+other.l_fonc[i]) elif type(other) in [types.FloatType,types.IntType] : for i in range(len(self.l_fonc)) : l_fonc.append(self.l_fonc[i]+other) - else: raise StandardError, 't_nappe : erreur de type dans __add__' + else: raise FonctionError, 't_nappe : erreur de type dans __add__' return t_nappe(self.vale_para,l_fonc,self.para) def __mul__(self,other) : - # multiplication avec une autre fonction ou un nombre, par surcharge de l'opérateur * + """multiplication avec une autre fonction ou un nombre, par surcharge de l'opérateur * + """ l_fonc=[] if isinstance(other,t_nappe): - if self.vale_para!=other.vale_para : raise StandardError, 'nappes à valeurs de paramètres différentes' + if self.vale_para!=other.vale_para : raise FonctionError, 'nappes à valeurs de paramètres différentes' for i in range(len(self.l_fonc)) : l_fonc.append(self.l_fonc[i]*other.l_fonc[i]) elif type(other) in [types.FloatType,types.IntType] : for i in range(len(self.l_fonc)) : l_fonc.append(self.l_fonc[i]*other) - else: raise StandardError, 't_nappe : erreur de type dans __mul__' + else: raise FonctionError, 't_nappe : erreur de type dans __mul__' return t_nappe(self.vale_para,l_fonc,self.para) def __repr__(self) : - # affichage de la nappe en double colonne + """affichage de la nappe en double colonne + """ texte=[] for i in range(len(self.vale_para)) : texte.append('paramètre : %f' % self.vale_para[i]) @@ -545,10 +594,11 @@ class t_nappe : return '\n'.join(texte) def homo_support(self,other) : - # renvoie la nappe self avec un support union de celui de self et de other - # le support est la discrétisation vale_para et les discrétisations des fonctions + """Renvoie la nappe self avec un support union de celui de self et de other + le support est la discrétisation vale_para et les discrétisations des fonctions + """ if self==other : return self - if self.para!=other.para : raise StandardError, 'combinaison de nappes à caractéristiques interpolation et prolongement différentes' + if self.para!=other.para : raise FonctionError, 'combinaison de nappes à caractéristiques interpolation et prolongement différentes' vale_para=self.vale_para.tolist()+other.vale_para.tolist() vale_para=dict([(i,0) for i in vale_para]).keys() vale_para.sort() @@ -565,11 +615,12 @@ class t_nappe : l_fonc.append(t_fonction(new_vale_x,new_vale_y,new_para)) if isinstance(other_fonc,t_fonction_c) : l_fonc.append(t_fonction_c(new_vale_x,new_vale_y,new_para)) - else : raise StandardError, 'combinaison de nappes : incohérence' + else : raise FonctionError, 'combinaison de nappes : incohérence' return t_nappe(vale_para,l_fonc,self.para) def extreme(self) : - # renvoie un dictionnaire des valeurs d'ordonnées min et max + """renvoie un dictionnaire des valeurs d'ordonnées min et max + """ val_min=min([min(fonc.vale_y) for fonc in self.l_fonc]) val_max=max([max(fonc.vale_y) for fonc in self.l_fonc]) vm={'min':[],'max':[]}