]> SALOME platform Git repositories - tools/eficas.git/blob - Aster/Cata/cataSTA8/Macro/macr_recal_ops.py
Salome HOME
Modif V6_4_°
[tools/eficas.git] / Aster / Cata / cataSTA8 / Macro / macr_recal_ops.py
1 #@ MODIF macr_recal_ops Macro  DATE 14/11/2006   AUTEUR ASSIRE A.ASSIRE 
2 # -*- coding: iso-8859-1 -*-
3 #            CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2002  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 # RESPONSABLE ASSIRE A.ASSIRE
21
22 import os, sys, types, copy, math
23 from glob import glob
24 import Numeric
25
26 debug = False
27
28 INFO = 1
29 NOMPRO = 'MACR_RECAL'
30
31 fichier_export = None
32 mode_python = False
33 type_fonctionnelle = 'float'
34
35 # --------------------------------------------------------------------------------------------------
36 def UTMESS(code,sprg,texte):
37    fmt='\n <%s> <%s> %s\n\n'
38    if INFO>0 or code=='F': print fmt % (code,sprg,texte)
39    if code=='F':
40       sys.exit()
41
42
43 # --------------------------------------------------------------------------------------------------
44 def Ecriture_Fonctionnelle(output_file, type_fonctionnelle, fonctionnelle):
45
46    try:    os.remove(output_file)
47    except: pass
48
49    f=open(output_file, 'w')
50    if type_fonctionnelle == 'vector':
51       fonctionnelle = str(fonctionnelle.tolist())
52       fonctionnelle = fonctionnelle.replace('[','')
53       fonctionnelle = fonctionnelle.replace(']','')
54    f.write(str(fonctionnelle))
55    f.close()
56
57
58 # --------------------------------------------------------------------------------------------------
59 def Ecriture_Derivees(output_file, derivees):
60
61    try:    os.remove(output_file)
62    except: pass
63
64    # On sort si il n'y a pas de derivees a imprimer
65    if not derivees: return
66
67    txt = ''
68    a = derivees
69    for l in range(len(a[:,0])):
70       ligne = []
71       for c in range(len(a[0,:])):
72          ligne.append( str(a[l,c]) )
73       txt += ','.join(ligne) + '\n'
74
75    f=open(output_file, 'w')
76    f.write(txt)
77    f.close()
78
79
80 # --------------------------------------------------------------------------------------------------
81 def Sortie(LIST_NOM_PARA, LIST_PARA, val, CALCUL_ASTER, Mess):
82    """Sortie de la macro, on renvoit les parametres obtenus"""
83
84    import Cata, aster, Macro
85    from Cata.cata import DEFI_LIST_REEL
86    from Accas import _F
87    from Utilitai.Utmess import UTMESS
88    from Macro import reca_message
89    from Macro import reca_algo
90    from Macro import reca_interp
91    from Macro import reca_utilitaires
92    from Macro import reca_calcul_aster
93    from Macro.reca_controles import gestion
94
95    if CALCUL_ASTER.METHODE != 'EXTERNE':
96       txt = "Nombre d'evaluation de la fonction : " + str(CALCUL_ASTER.evaluation_fonction)
97       UTMESS('I','MACR_RECAL',txt)
98       Mess.ecrire("\n"+txt)
99
100    LIST_NOM_PARA_ALPHA = [ para[0] for para in LIST_PARA ]
101    LIST_NOM_PARA_ALPHA.sort()
102    lival=[]
103    for i in LIST_NOM_PARA:
104       lival.append( val[ LIST_NOM_PARA_ALPHA.index(i) ] )
105    nomres = DEFI_LIST_REEL(VALE=lival)
106
107    return nomres
108
109
110 # --------------------------------------------------------------------------------------------------
111 def macr_recal_externe( RESU_EXP, LIST_PARA, RESU_CALC, UNITE_ESCL=3, POIDS=None, LIST_DERIV=None, 
112                ITER_MAXI=10, ITER_FONC_MAXI=100, RESI_GLOB_RELA=1.e-6, UNITE_RESU=91, PARA_DIFF_FINI=0.001,
113                GRAPHIQUE=None, SUIVI_ESCLAVE='NON', METHODE='EXTERNE', INFO=1, **args ):
114
115    METHODE='EXTERNE'
116
117    # Mot-cle GRAPHIQUE
118    if GRAPHIQUE:
119       GRAPHIQUE0 = {'INTERACTIF': 'NON', 'AFFICHAGE': 'TOUTE_ITERATION', 'UNITE': 90, 'FORMAT': 'XMGRACE'}
120       for k in GRAPHIQUE0.keys():
121          if not GRAPHIQUE.has_key(k): GRAPHIQUE[k] = GRAPHIQUE0[k]
122
123       if optparse_prefix_graph: args['prefix_graph'] = opts.prefix_graph
124       else:                     args['prefix_graph'] = os.getcwd() + os.sep + 'graph'
125
126    # Les parametres passes sur la ligne de commande surchargent les parametres de la commande MACR_RECAL
127    if optparse_INFO: INFO=opts.INFO
128    if optparse_follow_output:
129       if opts.follow_output == True: SUIVI_ESCLAVE='OUI'
130       else:                          SUIVI_ESCLAVE='NON'
131
132    if optparse_objective:
133       if type_fonctionnelle=='vector': args['FONCTIONNELLE']='VECTORIELLE'
134       else:                            args['FONCTIONNELLE']='SCALAIRE'
135
136    if optparse_gradient:
137       if   opts.gradient=='normal': args['GRADIENT']='NORMAL'
138       elif opts.gradient=='adim':   args['GRADIENT']='ADIMENSIONNE'
139       else:                         args['GRADIENT']='NON_CALCULE'
140
141
142    fonctionnelle, gradient = macr_recal(UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC, 
143                                         ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA, UNITE_RESU, PARA_DIFF_FINI,
144                                         GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args )
145
146    return fonctionnelle, gradient
147
148
149 # --------------------------------------------------------------------------------------------------
150 def macr_recal_ops(self,UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC, 
151                         ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA,UNITE_RESU,PARA_DIFF_FINI,
152                         GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args ):
153    """Macro commande realisant le recalage de modeles Aster"""
154    # Initialisation du compteur d'erreurs
155    ier=0
156
157    import aster
158    import Macro
159    from Cata import cata
160    from Cata.cata import DEFI_LIST_REEL, CREA_TABLE, TEST_TABLE
161
162    from Macro import reca_message
163    from Macro import reca_algo
164    from Macro import reca_interp
165    from Macro import reca_utilitaires
166    from Macro import reca_calcul_aster
167    from Macro.reca_controles import gestion
168    from Utilitai.Utmess import UTMESS
169
170    # Gestion des Exceptions
171    prev_onFatalError = aster.onFatalError()
172    aster.onFatalError('EXCEPTION')
173
174    # La macro compte pour 1 dans l'execution des commandes
175    self.set_icmd(1)
176
177    # Concept en sortir
178    self.DeclareOut('nomres',self.sd)
179
180    # Declaration de toutes les commandes Aster
181    for k,v in cata.__dict__.items() :
182      if type(v)==types.InstanceType:
183         if v.__class__.__name__ in ('OPER','MACRO'):
184            self.current_context[k]= v
185    self.current_context['_F']=cata.__dict__['_F']
186
187    macr_recal(UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC, 
188              ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA,UNITE_RESU,PARA_DIFF_FINI,
189              GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args)
190
191    return
192
193
194 # --------------------------------------------------------------------------------------------------
195 def macr_recal(UNITE_ESCL, RESU_EXP, POIDS, LIST_PARA, LIST_DERIV, RESU_CALC, 
196                ITER_MAXI, ITER_FONC_MAXI, RESI_GLOB_RELA,UNITE_RESU,PARA_DIFF_FINI,
197                GRAPHIQUE, SUIVI_ESCLAVE, METHODE, INFO, **args ):
198
199
200    # Import d'as_profil
201    if os.environ.has_key('ASTER_ROOT'):
202       sys.path.append(os.path.join(os.environ['ASTER_ROOT'], 'ASTK', 'ASTK_SERV', 'lib'))
203    else:
204       try:    sys.path.append(os.path.join(aster.repout, '..', 'ASTK', 'ASTK_SERV', 'lib'))
205       except: pass
206    try:
207       from as_profil import ASTER_PROFIL
208    except:
209       UTMESS('F','MACR_RECAL',"Impossible d'importer le module as_profil ! Vérifier la variable d'environnement ASTER_ROOT ou mettez a jour ASTK.")
210
211    import Macro, Utilitai
212    from Macro import reca_message
213    from Macro import reca_algo
214    from Macro import reca_interp
215    from Macro import reca_utilitaires
216    from Macro import reca_calcul_aster
217    from Macro.reca_controles import gestion
218    if( METHODE != 'EXTERNE'):
219       from Utilitai.optimize import fmin, line_search, line_search_BFGS, approx_fprime, approx_fhess_p, fminBFGS, fminNCG
220
221    if( METHODE == 'EXTERNE'):
222       pass
223    else:
224       if GRAPHIQUE:
225         dGRAPHIQUE=GRAPHIQUE[0].cree_dict_valeurs(GRAPHIQUE[0].mc_liste)
226         if dGRAPHIQUE.has_key('FORMAT') and dGRAPHIQUE['FORMAT'] == 'GNUPLOT':
227           # On essaie d'importer Gnuplot -> PAS DE GRAPHIQUE
228           try:
229             import Gnuplot
230           except ImportError:
231             GRAPHIQUE == None
232             if INFO>=1: UTMESS('A','MACR_RECAL',"Le logiciel Gnuplot ou le module python Gnuplot.py n'est pas disponible. On desactive l'affichage des courbes par Gnuplot.")
233
234
235    #_____________________________________________
236    #
237    # VERIFICATION PREALABLE SUR MEM_ASTER
238    #_____________________________________________
239
240    # Lecture du fichier .export
241    list_export = glob('*.export')
242    if len(list_export) == 0:
243       UTMESS('F','MACR_RECAL',"Probleme : il n'y a pas de fichier .export dans le repertoire de travail!")
244    elif len(list_export) >1:
245       UTMESS('F','MACR_RECAL',"Probleme : il y a plus d'un fichier .export dans le repertoire de travail!")
246
247    prof = ASTER_PROFIL(list_export[0])
248
249    mem_aster = prof['mem_aster'][0]
250    memjeveux = prof.args.get('memjeveux')
251
252    if mem_aster in ('', '100'):
253       if INFO>=1: UTMESS('A','MACR_RECAL',"Attention : il faut specifier une valeur pour 'mem_aster' (menu Option de ASTK) " \
254                               "pour limiter la memoire allouee au calcul maitre.")
255       mem_aster = '0'
256    if not memjeveux:
257       UTMESS('F','MACR_RECAL',"Probleme : aucune valeur pour le parametre 'memjeveux'. Verifier le .export")
258
259    try:
260       if mem_aster == '0':
261          memjeveux_esclave = float(memjeveux)
262       else:
263          memjeveux_esclave = float(memjeveux) / float(mem_aster) * 100. - float(memjeveux)
264    except:
265       UTMESS('F','MACR_RECAL',"Probleme : verifier les valeurs des parametres 'mem_aster' et 'memjeveux'")
266
267    if INFO>=1: UTMESS('I','MACR_RECAL',"Information : les calculs esclaves utiliseront : %.1f Mega Mots." % memjeveux_esclave)
268
269
270    #_____________________________________________
271    #
272    # INITIALISATIONS
273    #_____________________________________________
274
275    # Liste des parametres utilisant la sensibilité
276    if not LIST_DERIV: LIST_DERIV = {}
277    LIST_SENSI = LIST_DERIV.keys()
278
279    # Stocke l'ordre initial des parametres pour restituer dans le bon ordre les valeurs en sortie de la macro
280    LIST_NOM_PARA = [ para[0] for para in LIST_PARA ]
281
282    # On classe les parametres
283    LIST_SENSI.sort()
284    LIST_PARA.sort()
285
286    # Defini si on utilise le mot-clé SENSIBILITE pour IMPR_TABLE ou non
287    if len(LIST_SENSI) >0: table_sensibilite = True
288    else:                  table_sensibilite = False
289
290    # Defini si on ajoute l'echo des calculs esclaves dans le mess du calcul maitre
291    follow_output = False
292    if SUIVI_ESCLAVE and SUIVI_ESCLAVE=='OUI': follow_output = True
293 #   if( METHODE == 'EXTERNE') and mode_python: follow_output = opts.follow_output
294
295    # Pour les algorithmes d'optimize, on a des limitations
296    if METHODE in ['FMIN', 'FMINBFGS', 'FMINNCG']:
297       # On ne peut tracer qu'a la derniere iteration
298       if GRAPHIQUE:
299          if GRAPHIQUE['AFFICHAGE']=='TOUTE_ITERATION': UTMESS('I','MACR_RECAL',"Pour l'algorithme " + METHODE + " on ne peut tracer qu'a la derniere iteration")
300       # Les bornes ne sont pas gerees
301       UTMESS('I','MACR_RECAL',"Pour l'algorithme " + METHODE + " on ne tient pas compte des bornes sur les parametres.")
302
303    #_______________________________________________
304    #
305    # GESTION DE L'OPTION FACULTATIVE POUR LES POIDS
306    #_______________________________________________
307    if( POIDS == None):
308       POIDS=Numeric.ones(len(RESU_EXP))
309
310
311    #_____________________________________________
312    #
313    # GESTION DES ERREURS DE SYNTAXE
314    #_____________________________________________
315    texte_erreur = gestion(UNITE_ESCL,LIST_PARA,RESU_CALC,RESU_EXP,POIDS,GRAPHIQUE,UNITE_RESU,METHODE)
316    if (texte_erreur != ""):
317       UTMESS('F', "MACR_RECAL", texte_erreur)
318
319
320    #_____________________________________________
321    #
322    # INITIALISATIONS
323    #_____________________________________________
324
325    if( METHODE != 'EXTERNE'):
326      iter = 0
327      restant,temps_iter=0.,0.
328      restant,temps_iter,err=reca_utilitaires.temps_CPU(restant,temps_iter)
329
330    para,val,borne_inf,borne_sup = reca_utilitaires.transforme_list_Num(LIST_PARA,RESU_EXP)
331
332    # Pour l'algorithme externe, les valeurs sont celles lues dans le fichier input.txt
333    if( METHODE == 'EXTERNE') and mode_python: val = val_externe
334
335    val_init = copy.copy(val)
336
337    # OBJET "PARAMETRES GLOBAUX"
338    PARAMETRES = reca_calcul_aster.PARAMETRES(
339                                              METHODE=METHODE,
340                                              UNITE_RESU=UNITE_RESU,
341                                              INFO=INFO,
342                                              fich_output='./REPE_OUT/output_esclave.txt',
343                                              mode_include=False,
344                                              follow_output=follow_output,
345                                              table_sensibilite=table_sensibilite,
346                                              memjeveux_esclave=memjeveux_esclave,
347                                              PARA_DIFF_FINI=PARA_DIFF_FINI,
348                                              ITER_MAXI=ITER_MAXI,
349                                              ITER_FONC_MAXI=ITER_FONC_MAXI,
350                                              )
351
352    if( METHODE == 'EXTERNE'):
353       PARAMETRES.fich_output = './tmp_macr_recal/output_esclave.txt'
354       type_fonctionnelle = 'float'
355       if args.has_key('FONCTIONNELLE') and args['FONCTIONNELLE'] == 'VECTORIELLE':
356          PARAMETRES.vector_output = True
357          type_fonctionnelle = 'vector'
358
359    # On utilise le critere en erreur plutot que normalise
360    elif METHODE in ['FMIN', 'FMINBFGS', 'FMINNCG']: PARAMETRES.error_output = True
361
362    # OBJET "CALCUL"
363    CALCUL_ASTER = reca_calcul_aster.CALCUL_ASTER(PARAMETRES, UL=UNITE_ESCL, para=para, reponses=RESU_CALC, LIST_SENSI=LIST_SENSI, LIST_DERIV=LIST_DERIV)
364
365    # Instances des classes pour le calcul de l'erreur et le dimensionnemnt/adim
366    Simul = reca_interp.Sim_exp(RESU_EXP,POIDS)
367    Dim = reca_algo.Dimension(copy.copy(val_init),para)
368
369    CALCUL_ASTER.Simul     = Simul
370    CALCUL_ASTER.Dim       = Dim
371    CALCUL_ASTER.reca_algo = reca_algo
372
373    if (GRAPHIQUE):
374       CALCUL_ASTER.UNITE_GRAPHIQUE = GRAPHIQUE['UNITE']
375
376
377    # Instance de la classe gérant l'affichage des resultats du calcul de l'optimisation
378    Mess = reca_message.Message(para,RESU_EXP,copy.copy(val_init),UNITE_RESU) 
379
380    if( METHODE != 'EXTERNE'):
381       Mess.initialise()
382       txt = "Lancement de l'optimisation avec la methode : " + METHODE
383       if INFO>=1: UTMESS('I','MACR_RECAL',txt)
384       Mess.ecrire(txt)
385
386
387
388    #-------------------------------------------------------------------------------
389    # Methode EXTERNE (en fait juste une evaluation de la fonction puis on sort)
390    #
391    if( METHODE == 'EXTERNE'):
392
393       # On sauvegarde le fichier esclave si celui-ci est fort.UL (sinon il sera ecrase)
394       fic_esclave = './fort.'+str(UNITE_ESCL)
395       txt_old_esclave = None
396       if os.path.isfile(fic_esclave):
397          f = open(fic_esclave,'r')
398          txt_old_esclave = f.read()
399          f.close()
400       
401 #       try:    os.remove('./fort.'+str(UNITE_ESCL))
402 #       except: pass
403
404       # Fichier bilan
405       txt = '\nPARAMETRES : ' + str([ para[0] for para in LIST_PARA ]) + ' ' + str(val)
406       Mess.ecrire(txt)
407   
408       # Execution de l'esclave
409       if args.has_key('GRADIENT') and args['GRADIENT']!='NON_CALCULE':
410   
411          # Calcul de F et G
412          fonctionnelle, residu, A_nodim, A = CALCUL_ASTER.calcul_FG(val)
413
414          # Ecriture du fichier grad.txt contenant les derivees
415          if args['GRADIENT'] == 'ADIMENSIONNE': gradient = A
416          else:                                  gradient = A_nodim
417   
418          # Ecriture du fichier contenant le gradient
419          if not mode_python: Ecriture_Derivees(output_file='./fort.1901', derivees=gradient)
420
421       else:
422          # Calcul de F
423          fonctionnelle = CALCUL_ASTER.calcul_F(val)
424          gradient = None
425
426       # Ecriture du fichier contenant la fonctionnelle
427       if not mode_python: Ecriture_Fonctionnelle(output_file='./fort.1900', type_fonctionnelle=type_fonctionnelle, fonctionnelle=fonctionnelle)
428
429       # Fichier bilan
430       if type(fonctionnelle) == types.FloatType: txt = '---> fonctionnelle : '       + str(fonctionnelle)
431       else:                                      txt = '---> norme fonctionnelle : ' + str( math.sqrt( (Numeric.sum( [x**2 for x in fonctionnelle] )) ) )
432       Mess.ecrire(txt)
433
434       # Affichage de la valeur de la fonctionnelle
435       if mode_python and opts.INFO==-1: print txt
436
437       # Affichage de la norme du gradient (AA: a remplacer par une formule de norme L2 !!)
438       if gradient:
439          norme = 0
440          for l in range(len(gradient[:,0])):
441             for c in range(len(gradient[0,:])):
442                norme += ( gradient[l,c] * gradient[l,c] )
443          norme = math.sqrt(norme)
444          txt = '---> norme du gradient : ' + str(norme)
445          Mess.ecrire(txt)
446          if mode_python and opts.INFO==-1: print txt
447
448   
449       try:    os.remove('./fort.'+str(UNITE_ESCL))
450       except: pass
451
452       # On remet l'ancien fichier esclave si c'etait fort.UL
453       if txt_old_esclave:
454          f = open(fic_esclave,'w')
455          f.write(txt_old_esclave)
456          f.close()
457
458   
459       L_F = CALCUL_ASTER.L
460       iter = None
461
462       # On va ensuite jusqu'au bout (pour l'impression des graphes)
463
464
465
466    #-------------------------------------------------------------------------------
467    # Algorithme FMIN (pas d'adimensionnement car n'utilise pas de gradient)
468    #
469    elif( METHODE == 'FMIN'):
470       val, fval, warnflag = fmin(CALCUL_ASTER.calcul_F, val, maxiter=ITER_MAXI, maxfun=ITER_FONC_MAXI, fulloutput=1)
471
472       iter_fonc = CALCUL_ASTER.evaluation_fonction
473
474       Mess.ecrire("\nDerniere iteration : ")
475       Mess.affiche_etat_final_convergence(iter,ITER_MAXI,iter_fonc,ITER_FONC_MAXI, RESI_GLOB_RELA,residu=0,Act=[])
476       Mess.affiche_fonctionnelle(fval)
477       Mess.affiche_valeurs(val)
478       if warnflag==1: Mess.ecrire("Attention : le nombre maximum d'evaluations de la fonction (ITER_FONC_MAXI) a ete atteint")
479       if warnflag==2: Mess.ecrire("Attention : le nombre maximum d'iteration de l'algorithme (ITER_MAXI) a ete atteint")
480
481       nomres = Sortie(LIST_NOM_PARA, LIST_PARA, val, CALCUL_ASTER, Mess)
482       return
483
484    else:
485        #-------------------------------------------------------------------------------
486        # Pour tous les autres methodes, on adimensionne
487     
488        # Calcul d'initialisation de F, ici L_deriv_sensible ne contient que les termes calculés par la sensibilité, les autres termes sont nuls
489        L_init, L_deriv_sensible = CALCUL_ASTER.calcul_Aster(val, INFO)
490     
491        L_J_init, erreur = Simul.multi_interpole(L_init, RESU_CALC)
492        J_init = Simul.norme_J(copy.copy(L_J_init),copy.copy(L_J_init),UNITE_RESU)
493        J = J_init
494     
495        A = Simul.sensibilite(CALCUL_ASTER, L_init, L_deriv_sensible, val, PARA_DIFF_FINI)
496        A = Dim.adim_sensi(A)
497     
498        l = reca_algo.lambda_init(Numeric.matrixmultiply(Numeric.transpose(A),A))
499        gradient_init =reca_algo.calcul_gradient(A,erreur)  #utile pour le test de convergence, on prend les valeurs dimensionnées
500        residu = reca_algo.test_convergence(gradient_init,erreur,A,Numeric.zeros(len(gradient_init),Numeric.Float))
501     
502        Mess.affiche_result_iter(iter,J,val,residu,Numeric.array([]))
503        # On teste un manque de temps CPU
504        restant,temps_iter,err=reca_utilitaires.temps_CPU(restant,temps_iter)
505        if (err==1):
506           ier=ier+1
507           return ier
508
509        CALCUL_ASTER.L_init         = L_init
510        CALCUL_ASTER.L_J_init       = L_J_init
511        CALCUL_ASTER.J_init         = J_init
512        CALCUL_ASTER.A_init         = A
513        CALCUL_ASTER.gradient_init  = gradient_init
514        CALCUL_ASTER.residu_init    = residu
515
516
517        #-------------------------------------------------------------------------------
518        # Methode FMINBFGS et FMINNCG
519
520        if METHODE in ['FMINBFGS', 'FMINNCG']:
521           # Derivees
522           fprime=CALCUL_ASTER.calcul_G
523           warnflag=0
524
525           if args.has_key('GRADIENT') and args['GRADIENT'] == 'NON_CALCULE': fprime=None
526
527           if fprime: UTMESS('I','MACR_RECAL',"Les derivees sont calculees par Aster")
528           else:      UTMESS('I','MACR_RECAL',"Les derivees sont calculees par l'algorithme")
529
530           # Lancement de l'optimisation
531           if METHODE == 'FMINBFGS':
532              val, fval, func_calls, grad_calls, warnflag = fminBFGS(CALCUL_ASTER.calcul_F, val, fprime=fprime, maxiter=ITER_MAXI, avegtol=RESI_GLOB_RELA, fulloutput=1)
533
534           elif METHODE == 'FMINNCG':
535              val, fval, func_calls, grad_calls, hcalls, warnflag = fminNCG(CALCUL_ASTER.calcul_F, val, fprime=fprime, fhess_p=None, fhess=None, maxiter=ITER_MAXI, avextol=RESI_GLOB_RELA, fulloutput=1)
536
537           # Affichage des messages de sortie
538           iter_fonc = CALCUL_ASTER.evaluation_fonction
539           Mess.ecrire("\nDerniere iteration : ")
540           Mess.affiche_etat_final_convergence(iter,ITER_MAXI,iter_fonc,ITER_FONC_MAXI, RESI_GLOB_RELA,residu=0,Act=[])
541           Mess.affiche_fonctionnelle(fval)
542           Mess.affiche_valeurs(val)
543 #           if warnflag==1: Mess.ecrire("\nAttention : le nombre maximum d'evaluations de la fonction (ITER_FONC_MAXI) a ete atteint")
544 #           if warnflag==2: Mess.ecrire("\nAttention : le nombre maximum d'iteration de la methode (ITER_MAXI) a ete atteint")
545
546           # Permet d'avoir un diagnostic NOOK pour le job
547           if warnflag: iter=ITER_MAXI
548
549           L_F = CALCUL_ASTER.L
550           residu = fval
551
552
553
554
555        #-------------------------------------------------------------------------------
556        # Methode Levenberg-Marquardt
557        else:
558     
559              #_____________________________________________
560              #
561              # BOUCLE PRINCIPALE DE L'ALGORITHME
562              #_____________________________________________
563              epsilon = 10.*RESI_GLOB_RELA
564              while((residu > RESI_GLOB_RELA) & (iter<ITER_MAXI)):  
565                 iter = iter +1
566                 new_val, s, l, Act = reca_algo.Levenberg_bornes(val,Dim,val_init,borne_inf,borne_sup,A,erreur,l,UNITE_RESU) 
567
568                 # Calcul de F, ici L_deriv_sensible ne contient que les termes calculés par la sensibilité, les autres termes sont nuls
569                 L_F, L_deriv_sensible = CALCUL_ASTER.calcul_Aster(new_val, INFO)
570
571                 new_L_J,new_erreur = Simul.multi_interpole(L_F, RESU_CALC)
572                 new_J = Simul.norme_J(L_J_init,new_L_J,UNITE_RESU)
573                 l = reca_algo.actualise_lambda(l,Dim.adim(val),Dim.adim(new_val),A,erreur,new_J,J)
574
575                 val = copy.copy(new_val)
576                 erreur = copy.copy(new_erreur)
577                 J = new_J
578
579                 # Calcul de la matrice des sensibilites
580                 A = Simul.sensibilite(CALCUL_ASTER, L_F, L_deriv_sensible, val, PARA_DIFF_FINI)
581                 A = Dim.adim_sensi(A)
582
583                 # Calcul du residu
584                 residu = reca_algo.test_convergence(gradient_init,erreur,A,s)
585
586                 # Affichage iteration
587                 Mess.affiche_result_iter(iter,J,val,residu,Act)
588                 txt = "Informations de convergence :"
589                 txt += '\n=======================================================\n'
590                 txt += "Fin de l'iteration "+str(iter)+" :\n"
591                 txt += '\n=> Fonctionnelle = '+str(J)
592                 txt += '\n=> Residu        = '+str(residu)
593                 txt += '\n=======================================================\n'
594                 if INFO>=1: UTMESS('I','MACR_RECAL',txt)
595
596                 if (GRAPHIQUE):
597                    if GRAPHIQUE['AFFICHAGE']=='TOUTE_ITERATION':
598                       GRAPHE_UL_OUT=GRAPHIQUE['UNITE']
599                       interactif=(GRAPHIQUE['INTERACTIF']=='OUI')
600                       reca_utilitaires.graphique(GRAPHIQUE['FORMAT'],L_F,RESU_EXP,RESU_CALC,iter,GRAPHE_UL_OUT,interactif)
601
602                 # On teste un manque de temps CPU
603                 restant,temps_iter,err=reca_utilitaires.temps_CPU(restant,temps_iter)
604                 if (err==1):
605                    ier=ier+1
606                    return ier
607
608
609              #_____________________________________________
610              #
611              # FIN DES ITERATIONS
612              # CONVERGENCE OU ECHEC
613              #_____________________________________________
614              iter_fonc = CALCUL_ASTER.evaluation_fonction
615              Mess.affiche_etat_final_convergence(iter,ITER_MAXI,iter_fonc,ITER_FONC_MAXI, RESI_GLOB_RELA,residu,Act)
616              reca_algo.calcul_etat_final(para,A,iter,ITER_MAXI,RESI_GLOB_RELA,residu,Mess)
617
618
619        #-------------------------------------------------------------------------------
620
621
622    #_____________________________________________
623    #
624    # FIN DES ITERATIONS POUR TOUS LES ALGOS
625    #_____________________________________________
626    
627    if (GRAPHIQUE):
628       trace = False
629       fichier = None
630       # Pour les algorithmes d'optimize.py, on ne peut tracer qu'a la derniere iteration
631       if (GRAPHIQUE['AFFICHAGE']=='ITERATION_FINALE') or (METHODE in ['FMIN', 'FMINBFGS', 'FMINNCG']):
632          trace = True
633       if (METHODE=='EXTERNE' and GRAPHIQUE['AFFICHAGE']=='TOUTE_ITERATION'): 
634          trace = True
635          fichier = args['prefix_graph']
636       if trace:
637          if INFO>=1: UTMESS('I','MACR_RECAL',"Trace des graphiques")
638          GRAPHE_UL_OUT=GRAPHIQUE['UNITE']
639          interactif=(GRAPHIQUE['INTERACTIF']=='OUI')
640          reca_utilitaires.graphique(GRAPHIQUE['FORMAT'],L_F,RESU_EXP,RESU_CALC,iter,GRAPHE_UL_OUT,interactif,fichier)
641
642    if( METHODE == 'EXTERNE'):
643       if mode_python: return fonctionnelle, gradient
644
645 #   print residu, RESI_GLOB_RELA
646
647    # Si pas de convergence alors diagnostic NOOK_TEST_RESU
648    if residu > RESI_GLOB_RELA:
649       from Cata.cata import CREA_TABLE, TEST_TABLE
650       _tmp = []
651       _tmp.append( { 'PARA': 'ITER_MAXI', 'LISTE_R': 0.0, } )
652       motscle= {'LISTE': _tmp }
653
654       TBL=CREA_TABLE(**motscle);
655    
656       TEST_TABLE(TABLE=TBL,
657                  TYPE_TEST='SOMM',
658                  NOM_PARA='ITER_MAXI',
659                  VALE=1.,);
660
661    #_____________________________________________
662    #
663    # CREATIONS DE LA LISTE DE REELS CONTENANT 
664    # LES VALEURS DES PARAMETRES A CONVERGENCE
665    #_____________________________________________
666
667    
668    nomres = Sortie(LIST_NOM_PARA, LIST_PARA, val, CALCUL_ASTER, Mess)
669    return 
670
671
672
673
674
675
676
677
678
679
680
681
682
683 #-------------------------------------------------------------------------------
684 if __name__ == '__main__':
685
686     mode_python = True
687
688     from optparse import OptionParser, OptionGroup
689
690     p = OptionParser(usage='usage: %s fichier_export [options]' % sys.argv[0])
691     p.add_option('-i', '--input',        action='store',   dest='input',         type='string',   default='input.txt',   help='fichier contenant les parametres')
692     p.add_option('-o', '--output',       action='store',   dest='output',        type='string',   default='output.txt',  help='fichier contenant la fonctionnelle')
693     p.add_option('-g', '--output_grad',  action='store',   dest='output_grad',   type='string',   default='grad.txt',    help='fichier contenant le gradient')
694     p.add_option('-p', '--prefix_graph', action='store',   dest='prefix_graph',  type='string',                          help='prefixe des fichiers contenant les courbes')
695     p.add_option('-v', '--info',         action='store',   dest='INFO',          type='int',                             help='niveau de message (-1, 0, 1, 2)')
696     p.add_option('-f', '--follow',       action='store',   dest='follow_output', type='string',                          help="affiche ou non l'output du fichier Aster (True/False)")
697     p.add_option('-F', '--objective',    action='store',   dest='objective',     type='string',                          help="type de la fonctionnelle (float/vector)")
698     p.add_option('-G', '--gradient',     action='store',   dest='gradient' ,     type='string',   default='no',          help="calcul du gradient par Aster (no/normal/adim)")
699     p.add_option('-d', '--display',      action='store',   dest='display' ,      type='string',                          help="renvoi du DISPLAY (pour que la creation des courbes soit moins genante)")
700
701 #    p.add_option('-n', '--name',         action='store',   dest='name',          type='string',   default='optim',       help="prefixe du fichier de bilan")
702
703     opts, args = p.parse_args()
704
705     # renvoi du DISPLAY (pour que la creation des courbes soit moins genante)
706     if opts.display: os.environ['DISPLAY'] = opts.display
707
708
709     # Options par defaut
710     optparse_input = optparse_output = optparse_output_grad = optparse_prefix_graph = optparse_INFO = optparse_follow_output = optparse_objective = optparse_gradient = optparse_name = None
711
712     if opts.INFO==None: opts.INFO=0
713
714     if opts.input:                                 optparse_input         = True
715     if opts.output:                                optparse_output        = True
716     if opts.output_grad:                           optparse_output_grad   = True
717     if opts.prefix_graph:                          optparse_prefix_graph  = True
718     if opts.INFO in [-1, 0, 1, 2]:                 optparse_INFO          = True
719     if opts.follow_output in ['True', 'False']:    optparse_follow_output = True
720     if opts.objective in ['float', 'vector']:      optparse_objective     = True
721     if opts.gradient in ['no', 'normal', 'adim']:  optparse_gradient      = True
722 #    if opts.name:                                  optparse_name          = True
723
724     if opts.follow_output=='True':  opts.follow_output=True
725     if opts.follow_output=='False': opts.follow_output=False
726
727
728     # Fichier .export
729     if args:
730        fichier_export =  args[0]
731        if not os.path.isfile(fichier_export): fichier_export = None
732
733     INFO = opts.INFO
734     input_file  = opts.input
735     output_file = opts.output
736     output_grad = opts.output_grad
737     type_fonctionnelle = opts.objective
738
739     # Import d'as_profil
740     if os.environ.has_key('ASTER_ROOT'):
741       sys.path.append(os.path.join(os.environ['ASTER_ROOT'], 'ASTK', 'ASTK_SERV', 'lib'))
742     try:
743       from as_profil import ASTER_PROFIL
744     except:
745       UTMESS('F','MACR_RECAL',"Impossible de determiner l'emplacement d'Aster ! Fixer le chemin avec la variable d'environnement ASTER_ROOT.")
746
747     # Efface les fichiers resultats
748     try:    os.remove(output)
749     except: pass
750     try:    os.remove(output_grad)
751     except: pass
752
753
754     # Si le fichier export n'est pas en argument on prend l'export qui est dans le rep courant
755     if not fichier_export:
756       # Lecture du fichier .export
757       list_export = glob('*.export')
758       if len(list_export) != 1:
759          UTMESS('F','MACR_RECAL',"Impossible de determiner le fichier .export a utiliser. Specifier le sur la ligne de commande.")
760       else:
761          fichier_export = list_export[0]
762     prof = ASTER_PROFIL(fichier_export)
763
764     # Execution du fichier .comm
765     nom_comm = None
766     # fichier/répertoire
767     for lab in ('data', 'resu'):
768       l_fr = getattr(prof, lab)
769       l_tmp = l_fr[:]
770
771       for dico in l_tmp:
772         # fichiers
773         if not dico['isrep']:
774           # Ancien .comm a executer
775           if dico['type'] == 'comm' and dico['ul'] == '1':
776             nom_comm = dico['path']
777
778     # parametres
779     for lab in ('param',):
780       l_fr = getattr(prof, lab)
781 #      print l_fr
782 #      print l_fr['version']
783       try:    os.environ['ASTER_VERSION'] = l_fr['version'][0]
784       except: pass
785
786
787     if not nom_comm:
788        UTMESS('F','MACR_RECAL',"Probleme : le fichier .comm n'est pas defini dans le .export.")
789     if not os.path.isfile(nom_comm):
790        UTMESS('F','MACR_RECAL',"Probleme : le fichier .comm suivant n'est pas defini : " + nom_comm)
791
792
793
794     # -------------------------------------------------------------------
795     # Lecture des valeurs d'entree
796     if INFO==2: UTMESS('I',NOMPRO,"Lecture du fichier : " + input_file)
797     try:
798        f = open(input_file, 'r')
799        txt = f.read()
800        f.close()
801        txt = txt.replace(',', ' ')
802        val_externe = [ float(x) for x in txt.strip().split() ]
803     except:
804        UTMESS('F',NOMPRO,"Probleme : impossible de lire le fichier d'entree :\n" + input_file)
805     if INFO>=2: UTMESS('I',NOMPRO,"Parametres d'entree : " + str(val_externe))
806     if optparse_INFO and opts.INFO == -1: print '\n'+ str(val_externe)
807
808
809     # -------------------------------------------------------------------
810     # Efface les fichiers d'entree et de sortie
811     try:    os.remove(input_file)
812     except: pass
813     try:    os.remove(output_file)
814     except: pass
815     try:    os.remove(output_grad)
816     except: pass
817
818
819
820
821     # --------------------------------------------------------------------------------------------------------
822     # --------------------------------------------------------------------------------------------------------
823     # --------------------------------------------------------------------------------------------------------
824     # Ci-dessous on extrait le fichier de commande jusqu'a la commande MACR_RECAL exclue (fichiernew)
825     # Puis la commande MACR_RECAL (commandenew)
826     # Ensuite on annule l'effet des commandes Aster et on evalue en Python les deux chaines de textes
827
828     # Lecture du fichier .comm
829     f=open(nom_comm,'r')
830     fichier=f.read()
831     f.close
832
833     # Extraction des deux parties dans le fichier de commande
834     fichiernew=None
835     commandenew=None
836     nb_par=-99
837     txt1='MACR_RECAL'
838     txt2='('
839     txt3=')'
840     for ligne in fichier.split('\n'):
841        if ligne.find( txt1 )!=-1 and ligne.find( txt2 )!=-1 and ligne.strip()[0]!='#':
842           nb_par=0
843           index_deb1 = fichier.index(ligne)
844           fichiernew=fichier[:index_deb1]
845 #          if debug: print 80*'*' + 2*'\n'+fichiernew+80*'*' + 2*'\n'
846        if fichiernew and ligne.find( txt2 )!=-1: nb_par+=1
847        if fichiernew and ligne.find( txt3 )!=-1: nb_par-=1
848        if fichiernew and nb_par==0:
849           index_fin1 = fichier.index(ligne)+len(ligne)
850           commandenew=fichier[index_deb1:index_fin1]
851
852           # Remplace le nom de concept a gauche du signe egal
853           index_deb2 = commandenew.index(txt1)
854           commandenew='fonctionnelle, gradient='+commandenew[index_deb2:]+ '\n'
855
856           if debug: print 80*'*' + 2*'\n'+commandenew+80*'*' + 2*'\n'
857           break
858     if not fichiernew or not commandenew:
859        txt = "Probleme : Le fichier de commande :\n" + nom_comm + "\n ne semble pas comporter la commande MACR_RECAL"
860        UTMESS('F',NOMPRO,txt)
861
862
863     # -------------------------------------------------------------------
864     # Import du module Utilitai
865     sys.path.append(os.path.join(os.getcwd(), 'Python'))
866     sys.path.append(os.path.join(os.environ['ASTER_ROOT'], os.environ['ASTER_VERSION'], 'bibpyt'))
867     try:
868        import Utilitai
869        from Utilitai.System import ExecCommand
870     except:
871        UTMESS('F','MACR_RECAL',"Probleme : impossible d'importer le module Utilitai! Prevenir la maintenance.")
872
873
874     # -------------------------------------------------------------------
875     # On annule les commandes Aster du fichier maitre .comm
876     def DEBUT(*args, **kwargs): pass
877     def FIN(*args, **kwargs): pass
878     def MACR_RECAL(*args, **kwargs): pass
879     def _F(*args, **kwargs): return kwargs
880     def DEFI_LIST_REEL(*args, **kwargs): pass
881     def DEFI_FONCTION(*args, **kwargs): pass
882     def TEST_FONCTION(*args, **kwargs): pass
883     def DEFI_CONSTANTE(*args, **kwargs): pass
884
885
886     # -------------------------------------------------------------------
887     # Evaluation du fichier de commande Aster jusqu'a MACR_RECAL
888     lance_aster = False
889     try:
890        exec(fichiernew)
891     except:
892        txt = "Le mode EXTERNE tourne en mode degrade. Lire la documentation."
893        UTMESS('A',NOMPRO,txt)
894        lance_aster = True
895     else:
896        exec(commandenew.replace(txt1, 'macr_recal_externe'))
897 #        try:
898 #           exec(commandenew.replace(txt1, 'macr_recal_externe'))
899 #        except Exception, err:
900 #           print err
901 #           txt = "Erreur lors de l'execution de la commande MACR_RECAL" 
902 #           UTMESS('F',NOMPRO,txt)
903
904        Ecriture_Fonctionnelle(output_file, type_fonctionnelle, fonctionnelle)
905        Ecriture_Derivees(output_grad, gradient)
906
907
908
909     # --------------------------------------------------------------------------------------------------------
910     # --------------------------------------------------------------------------------------------------------
911     # --------------------------------------------------------------------------------------------------------
912     # Si l'evaluation du fichier de commande Aster jusqu'a MACR_RECAL a echoue, on execute Aster "normalement"
913     if lance_aster:
914
915        _PARAM_ = '_PARAM_'
916        new_fichier_comm = os.getcwd() + os.sep + 'tmp_comm'
917        new_fichier_export  = os.getcwd() + os.sep + fichier_export.split('/')[-1] + '_new'
918
919        # Lecture du fichier .comm
920        f=open(nom_comm,'r')
921        fichier=f.read()
922        f.close
923     
924        # -------------------------------------------------------------------
925        # Modification du fichier .comm (changement des valeurs, ecriture du resultat dans un fichier)
926        if INFO==2: UTMESS('I',NOMPRO,"Lecture du fichier : " + nom_comm)
927        f = open(nom_comm, 'r')
928        ok1 = ok3 = ok4 = False
929        txt = ''
930        for ligne in f:
931           if ligne.find('MACR_RECAL')!=-1 and ligne.strip()[0]!='#':            # On determine le nom du concept sortant de MACR_RECAL
932              ok3 = True
933              _RESU_ = ligne.split('=')[0].strip()
934              txt += ligne
935           elif ligne.strip()[:len(_PARAM_)] == _PARAM_:                        # On change les parametres : la variables _PARAM_
936              ok1 = True
937              txt += _PARAM_ + " = " + str(val_externe) + '\n'
938           elif ligne.find('METHODE')!=-1 and ligne.strip()[0]!='#':         # On verifie bien que la methode externe est choisi
939              if ligne.find("EXTERNE")!=-1:
940                 ok4 = True
941                 txt += ligne
942           else: txt += ligne
943        f.close()
944
945        if not ok1:  UTMESS('F',NOMPRO,"Probleme : il faut mettre les parametres sous la forme d'une ligne python " + str(_PARAM_) + " = [param1, param2, ...]")
946        if not ok3:  UTMESS('F',NOMPRO,"Probleme : la commande MACR_RECAL n'a pas ete trouvee dans le .comm")
947        if not ok4:  UTMESS('F',NOMPRO,"Probleme : dans la commande MACR_RECAL, il faut choisir METHODE='EXTERNE'")
948
949        txt = txt.replace('_RESU_', _RESU_)
950
951        # Ecriture du nouveau fichier comm temporaire
952        if INFO==2: UTMESS('I',NOMPRO,"Ecriture du fichier : " + new_fichier_comm)
953        f = open(new_fichier_comm, 'w')
954        f.write(txt)
955        f.close()
956
957        # On remplace dans l'export par le nouveau .comm
958        prof = ASTER_PROFIL(fichier_export)
959        for lab in ('data', 'resu'):
960           l_fr = getattr(prof, lab)
961           l_tmp = l_fr[:]
962           for dico in l_tmp:
963              # fichiers
964              if not dico['isrep']:
965                 # On remplace par le nouveau .comm
966                 if dico['type'] == 'comm' and dico['ul'] == '1':
967                    dico['path'] = new_fichier_comm
968
969 #              if lab == 'resu':
970 #                 dico['path'] = os.path.join(tmp_macr_recal, os.path.basename(dico['path']))
971
972        # On ajoute au profil le fichier output.txt (unite logique 1900)
973        try:    os.remove('./fort.1900')
974        except: pass
975        if not output_file.find(os.sep)!=-1: output_file = os.getcwd() + os.sep + output_file
976        prof.Set('R', {'type':'libr', 'isrep':False, 'path': output_file, 'ul':1900, 'compr': False} )
977
978        # On ajoute au profil le fichier grad.txt (unite logique 1901)
979        if optparse_gradient and opts.gradient!='no':
980           try:    os.remove('./fort.1901')
981           except: pass
982           output_grad = opts.gradient
983           if not output_grad.find(os.sep)!=-1: output_grad = os.getcwd() + os.sep + output_grad
984           prof.Set('R', {'type':'libr', 'isrep':False, 'path': output_grad, 'ul':1901, 'compr': False} )
985
986
987        # Ecriture du nouveau fichier export
988        try:
989           if INFO==2: UTMESS('I',NOMPRO,"Ecriture du fichier : " + new_fichier_export)
990           prof.WriteExportTo(new_fichier_export)
991        except:
992           UTMESS('F',NOMPRO,"Probleme : Impossible d'ecrire le fichier export : " + new_fichier_export)
993        prof.WriteExportTo('/tmp/exp')
994
995
996        # chemin vers as_run
997        if os.environ.has_key('ASTER_ROOT'):
998           as_run = os.path.join(os.environ['ASTER_ROOT'], 'ASTK', 'ASTK_SERV', 'bin', 'as_run')
999        else:
1000           as_run = 'as_run'
1001           if INFO>=1: UTMESS('A', nompro, "Variable d'environnement ASTER_ROOT absente, " \
1002                                "on essaiera avec 'as_run' dans le $PATH.")
1003
1004
1005        # Import du module Utilitai
1006        sys.path.append(os.path.join(os.environ['ASTER_ROOT'], os.environ['ASTER_VERSION'], 'bibpyt'))
1007        try:
1008           import Utilitai
1009           from Utilitai.System import ExecCommand
1010        except:
1011           UTMESS('F','MACR_RECAL',"Probleme : impossible d'importer le module Utilitai! Prevenir la maintenance.")
1012
1013
1014        # Lancement d'Aster avec le deuxieme export
1015        cmd = '%s %s' % (as_run, new_fichier_export)
1016        if INFO>=2: UTMESS('I','MACR_RECAL',"Lancement de la commande : " + cmd)
1017        iret, txt_output = ExecCommand(cmd, follow_output=opts.follow_output,verbose=opts.follow_output)
1018        if INFO>=2: UTMESS('I','MACR_RECAL',"Fin du lancement de la commande : " + cmd)
1019
1020        try:    os.remove(new_fichier_comm)
1021        except: pass
1022        try:    os.remove(new_fichier_export)
1023        except: pass
1024
1025