]> SALOME platform Git repositories - tools/eficas.git/blob - Aster/Cata/cataSTA76/Macro/test_fichier_ops.py
Salome HOME
Modif V6_4_°
[tools/eficas.git] / Aster / Cata / cataSTA76 / Macro / test_fichier_ops.py
1 #@ MODIF test_fichier_ops Macro  DATE 24/05/2006   AUTEUR CIBHHLV L.VIVAN 
2 # -*- coding: iso-8859-1 -*-
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2004  EDF R&D                  WWW.CODE-ASTER.ORG
6 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY  
7 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY  
8 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR     
9 # (AT YOUR OPTION) ANY LATER VERSION.                                                  
10 #                                                                       
11 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT   
12 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF            
13 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU      
14 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.                              
15 #                                                                       
16 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE     
17 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,         
18 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.        
19 # ======================================================================
20
21 import sys
22 import os.path
23 import re
24 from math import floor, log10
25 from types import StringType
26 import md5
27
28 #-------------------------------------------------------------------------------
29 def test_fichier_ops(self, UNITE, FICHIER, NB_CHIFFRE, EPSILON, VALE_K, INFO, **args):
30    """
31      Macro TEST_FICHIER permettant de tester la non-regression d'un fichier
32      'a une tolerance' pres pour les nombres reels en calculant
33      le md5sum.
34    """
35    ier = 0
36    # La macro compte pour 1 dans la numerotation des commandes
37    self.set_icmd(1)
38
39    # On importe les definitions des commandes a utiliser dans la macro
40    # Le nom de la variable doit etre obligatoirement le nom de la commande
41    INFO_EXEC_ASTER = self.get_cmd('INFO_EXEC_ASTER')
42    DETRUIRE        = self.get_cmd('DETRUIRE')
43    CREA_TABLE      = self.get_cmd('CREA_TABLE')
44    TEST_TABLE      = self.get_cmd('TEST_TABLE')
45    
46    import aster
47    from Accas import _F
48    from Macro.test_fichier_ops import md5file
49    from Utilitai.Utmess import UTMESS
50
51    # vérifie la syntaxe des expressions régulières fournies
52    l_regexp = []
53    if args['EXPR_IGNORE']:
54       if type(args['EXPR_IGNORE']) is StringType:
55          lexp = [args['EXPR_IGNORE']]
56       else:
57          lexp = args['EXPR_IGNORE']
58       for exp in lexp:
59          try:
60             obj = re.compile(exp)
61          except re.error, s:
62             UTMESS('F', 'TEST_FICHIER',
63                    '<INVALID_REGEXP> %s pour %s' % (str(s), repr(exp)))
64          else:
65             l_regexp.append(exp)
66
67    is_ok = 0
68
69    # vérifier que le fichier a été fermé
70    tinfo__ = INFO_EXEC_ASTER(LISTE_INFO='ETAT_UNITE', FICHIER=FICHIER)
71    
72    if tinfo__['ETAT_UNITE', 1].find('OUVERT')>-1:
73       UTMESS('A',  'TEST_FICHIER',
74              "LE FICHIER N'A PAS ETE FERME :\n%s" % FICHIER)
75
76    # fichier correctement fermé
77    else:
78       # calcule le md5sum du fichier
79       ier, mdsum = md5file(FICHIER, NB_CHIFFRE, EPSILON, l_regexp, INFO)
80       if ier != 0:
81          if ier == 4:
82             texte_erreur = 'Fichier inexistant : '+FICHIER
83          else:
84             texte_erreur = 'Erreur dans md5file, code retour = '+str(ier)
85          texte_erreur = '<S> <TEST_FICHIER> '+texte_erreur
86          # aujourd'hui, je ne sais pas déclencher autre chose que <F>...
87          self.cr.fatal(texte_erreur)
88          return ier
89
90       # comparaison a la reference
91       if INFO > 0 :
92       #   aster.affiche('MESSAGE', ' %-20s : %32s\n' % ('REFERENCE', VALE_K))
93          print ' %-20s : %32s' % ('REFERENCE',VALE_K)
94          print
95
96       if mdsum == VALE_K:
97          is_ok = 1
98
99    # produit le TEST_TABLE
100    tab1__ = CREA_TABLE(LISTE=(_F(PARA='TEST',
101                                  TYPE_K='K8',
102                                  LISTE_K='VALEUR  ',),
103                               _F(PARA='BOOLEEN',
104                                  LISTE_I=is_ok,),),)
105    if args['REFERENCE'] == 'NON_REGRESSION':
106       TEST_TABLE(TABLE=tab1__,
107                  FILTRE=_F(NOM_PARA='TEST',
108                            VALE_K='VALEUR  ',),
109                  NOM_PARA='BOOLEEN',
110                  VALE_I=1,
111                  PRECISION=1.e-3,
112                  CRITERE='ABSOLU',
113                  REFERENCE=args['REFERENCE'],
114                  VERSION=args['VERSION'],)
115    else:
116       TEST_TABLE(TABLE=tab1__,
117                  FILTRE=_F(NOM_PARA='TEST',
118                            VALE_K='VALEUR  ',),
119                  NOM_PARA='BOOLEEN',
120                  VALE_I=1,
121                  PRECISION=1.e-3,
122                  CRITERE='ABSOLU',
123                  REFERENCE=args['REFERENCE'],)
124
125    DETRUIRE(CONCEPT=_F(NOM=('tinfo__','tab1__'),),
126             ALARME='NON',INFO=1,)
127    return ier
128
129
130 #-------------------------------------------------------------------------------
131 def sign(x):
132    return int(x/abs(x))
133
134 def _round(x, n, exp):
135    v = x * 10**(-exp+n)
136    val = int(v + sign(x)*0.4999)
137    return val
138
139 def entier_ini(x, nbch, exp=None):
140    #if exp is None:
141       #exp = int(floor(log10(abs(x))))
142    val = _round(x, nbch-1, exp)
143    return val, exp-nbch+1
144
145 def entier_triple(x, nbch, exp_epsi):
146    #if abs(x) <= 10**exp_epsi:
147       #return '0'
148    y = _round(x * 10**(-exp_epsi), 0, 0) * 10**exp_epsi
149    exp = int(floor(log10(abs(y))))
150    z1, e1 = entier_ini(y,           nbch+2, exp)
151    z2, e2 = entier_ini(z1 * 10**e1, nbch+1, exp)
152    z3, e3 = entier_ini(z2 * 10**e2, nbch,   exp)
153    return '%sE%d' % (z3, e3)
154
155 #-------------------------------------------------------------------------------
156 def md5file(fich, nbch, epsi,
157             regexp_ignore=[], info=0, output=None, format_func=entier_triple):
158    """
159    Cette methode retourne le md5sum d'un fichier en arrondissant les nombres
160    reels a la valeur significative.
161    IN :
162       fich          : nom du fichier
163       nbch          : nombre de decimales significatives
164       epsi          : valeur en deca de laquelle on prend 0
165       regexp_ignore : liste d'expressions régulières permettant d'ignorer
166          certaines lignes
167       output        : pour rediriger l'interprétation du fichier (INFO=2)
168          dans le fichier de nom `output`,
169       info          : on affiche le résumé si info>0
170       format_func   : on peut préciser une autre fonction pour formatter 
171          les réels...
172    OUT :
173       code retour : 0 si ok, >0 sinon
174       md5sum
175    
176          NE PAS AJOUTER D'IMPORT QUI RENDRAIT CETTE FONCTION
177                INUTILISABLE EN DEHORS DE CODE_ASTER.
178    """   
179    if output != None:
180       try:
181          sys.stdout = open(output, 'w')
182       except IOError, msg:
183          print "Erreur d'écriture sur %s : %s" % (output, msg)
184    
185    #      1 Mo   10 Mo   100 Mo
186    # v0   2.6 s  20.4 s  196.6 s
187    # v1   2.0 s  10.3 s  94.9 s (pas de distinction entier/reel)
188    # remplacer le try/except par if re.search(...), 80% plus lent
189    # v2  10.7 s
190    if not os.path.isfile(fich):
191       return 4, ''
192    f = open(fich,'r')
193    m = md5.new()
194    exp_epsi = int(floor(log10(abs(epsi))))
195    i = 0
196    for ligne in f:
197       i = i+1
198       if info >= 2:
199          print 'LIGNE', i,
200       keep = True
201       for exp in regexp_ignore:
202          if re.search(exp, ligne):
203             keep = False
204             if info >= 2:
205                print ' >>>>>>>>>> IGNOREE <<<<<<<<<<',
206             break
207       if keep:
208          # découpe des nombres collés : 1.34E-142-1.233D+09
209          ligne = re.sub('([0-9]+)\-', '\g<1> -', ligne)
210          # conversion des DOUBLE fortran en 'E'
211          ligne = re.sub('([0-9]+)[dD]([\-\+]{0,1}[0-9]+)', '\g<1>E\g<2>', ligne)
212          r = ligne.split()
213          for x in r:
214             try:
215                xv = float(x)
216                if abs(xv)<epsi:
217                   s = '0'
218                else:
219                   #s = format_float % float(x)
220                   s = format_func(xv, nbch, exp_epsi)
221             except ValueError:
222                s = x
223             if info >= 2:
224                print (' %'+str(nbch+7)+'s') % s,
225             m.update(s)
226       if info >= 2:
227          print
228    f.close()
229    md5sum = m.hexdigest()
230    
231    affich_resu = True
232    if info >= 1:
233       while affich_resu:
234          form = ' %-20s : %32s'
235          print form % ('Fichier', fich)
236          print form % ('Nombre de lignes', str(i))
237          #print form % ('Format des reels',format_float)
238          print form % ('Nombre de chiffres', str(nbch))
239          print form % ('Epsilon', str(epsi))
240          print form % ('md5sum', md5sum)
241          if output == None:
242             affich_resu = False
243          else:
244             sys.stdout = sys.__stdout__
245             output = None
246    return 0, md5sum
247
248
249 #-------------------------------------------------------------------------------
250 if __name__ == '__main__':
251    from optparse import OptionParser, OptionGroup
252
253    p = OptionParser(usage='usage: %s a_tester [options]' % sys.argv[0])
254    p.add_option('-n', '--nbch',
255       action='store', dest='nbch', type='int', default=6,
256       help='nombre de chiffres significatifs')
257    p.add_option('-e', '--epsilon',
258       action='store', dest='epsi', type='float', default=1.e-14,
259       help='epsilon en dessous duquel on considère les nombres nuls')
260    p.add_option('--expr_ignore',
261       action='store', dest='exp', type='string',
262       help='expression régulière à ignorer')
263    p.add_option('-o', '--output',
264       action='store', dest='output', type='string', default='output.txt',
265       help='fichier de sortie')
266    opts, args = p.parse_args()
267
268    if len(args)<1:
269       p.print_usage()
270       sys.exit(1)
271    if opts.exp is None:
272       exp = []
273    else:
274       exp = [opts.exp]
275
276    print 'Lignes retenues dans %s' % opts.output
277    iret = md5file(args[0], opts.nbch, opts.epsi,
278                   regexp_ignore=exp, info=2, output=opts.output)
279