1 #@ MODIF calc_spec_ops Macro DATE 11/05/2010 AUTEUR COURTOIS M.COURTOIS
3 # CONFIGURATION MANAGEMENT OF EDF VERSION
4 # ======================================================================
5 # COPYRIGHT (C) 1991 - 2008 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.
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.
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 # ======================================================================
23 from SD.sd_fonction import sd_fonction
25 # -----------------------------------------------------------------------------
26 class FonctionError(Exception): pass
27 class ParametreError(FonctionError): pass # probleme de NOM_PARA
28 class InterpolationError(FonctionError): pass
29 class ProlongementError(FonctionError): pass
31 # -----------------------------------------------------------------------------
34 def calc_spec_ops(self,TAB_ECHANT,ECHANT,INTERSPE,TRANSFERT,TITRE,INFO,**args):
35 # ------------------------------------------------------------------
36 # Calcul d'une matrice interspectrale
37 # a partir de fonctions reelles
40 from types import ListType, TupleType
41 EnumTypes = (ListType, TupleType)
43 from Utilitai.Utmess import UTMESS
45 import numpy.fft as FFT
50 # La macro compte pour 1 dans la numerotation des commandes
53 # Le concept sortant (de type table_sdaster ou derive) est tab
54 self.DeclareOut('tabout', self.sd)
56 # On importe les definitions des commandes a utiliser dans la macro
57 # Le nom de la variable doit etre obligatoirement le nom de la commande
58 CREA_TABLE = self.get_cmd('CREA_TABLE')
59 CALC_TABLE = self.get_cmd('CALC_TABLE')
60 DEFI_FONCTION = self.get_cmd('DEFI_FONCTION')
62 #--- Verifications sur les entrees --#
64 if (ECHANT==None and TAB_ECHANT==None) :
65 raise FonctionError, 'Vous devez specifier des fonctions en entree'
67 if TAB_ECHANT==None : TAB_ECHANT=[]
68 if ECHANT==None : ECHANT=[]
69 if INTERSPE==None : INTERSPE=[]
70 if TRANSFERT==None : TRANSFERT=[]
71 if len(TAB_ECHANT)*len(ECHANT) !=0 :
72 raise FonctionError, 'Vous pouvez specifier une table_fonction ou' + ' une liste de fonctions en entree, mais pas les deux'
73 if len(TRANSFERT)*len(INTERSPE) !=0 :
74 raise FonctionError, 'Vous ne pouvez specifier qu' +"'"+'un type de calcul par appel'
78 #-- Recuperation des entrees --#
84 # for occ in TAB_ECHANT :
85 # l_t.append(('TAB_ECHANT',occ))
87 l_t = TAB_ECHANT.List_F()[0]
90 l_f.append(('ECHANT',occ))
92 l_G.append(('INTERSPE',occ))
93 for occ in TRANSFERT :
94 l_H.append(('TRANSFERT',occ))
97 # Pour dimensionner les fenetres :
98 # Cas ECHANT : on recupere simplement la premiere fonction
99 # Cas_TAB_ECHANT : on recupere toutes les fonctions
102 vale_sig=l_f[0][1]['FONCTION'].Valeurs();
103 l_ech=len(vale_sig[0])
104 dt=vale_sig[0][1]-vale_sig[0][0]
105 print "test : l_ech = ", l_ech
107 #tab_ast=l_t[0][1]['NOM_TAB'];
108 tab_ast=l_t['NOM_TAB'] #MC
109 tab_py=tab_ast.EXTR_TABLE();
111 nom_fonc= tab_py['FONCTION'].values()['FONCTION']
112 fonc_py = [sd_fonction(fonc) for fonc in nom_fonc]
113 temp=fonc_py[0].VALE.get();
116 l_ech_temp=l_t['LONGUEUR_ECH'];
117 recouvr_temp=l_t['RECOUVREMENT'];
119 l_ech_t=[l_ech_temp[0]['DUREE'] , l_ech_temp[0]['POURCENT'],l_ech_temp[0]['NB_PTS'] ];
120 recouvr_t=[recouvr_temp[0]['DUREE'] , recouvr_temp[0]['POURCENT'],recouvr_temp[0]['NB_PTS'] ];
122 if l_ech_t.count(None)==3 : l_ech=len(temp)/2;
123 if recouvr_t.count(None)==3 : recouvr=0;
124 if l_ech_t.count(None)<2 :
125 raise FonctionError, 'Vous ne pouvez utiliser qu'+"'"+ 'un mot clef pour definir la longueur des echantillons'
126 if recouvr_t.count(None)<2 :
127 raise FonctionError, 'Vous ne pouvez utiliser qu'+"'"+'un mot clef pour definir la longueur de recouvrement des echantillons'
129 if l_ech_t[i1] !=None :
131 l_ech=int(numpy.floor(l_ech_t[i1]/dt));
133 l_ech=int(numpy.floor((len(temp)/2)*l_ech_t[i1]*0.01));
135 l_ech=int(numpy.floor(l_ech_t[i1]))
136 if l_ech > len(temp)/2 :
137 raise FonctionError, 'Vous devez specifier une longueur d'+"'"+'echantillon inferieure a la longueur totale de l'+"'"+'acquisition'
139 if recouvr_t[i1] !=None :
141 recouvr=int(numpy.floor(recouvr_t[i1]/dt));
143 recouvr=int(numpy.floor((l_ech)*recouvr_t[i1]*0.01));
145 recouvr=int(numpy.floor(recouvr_t[i1]))
147 raise FonctionError, 'La longueur de recouvrement ne peut exceder la longueur '
148 print "test2 : l_ech = ", l_ech
150 #-- Recuperation des fenetres
154 if occ[1]['FENETRE'] == 'RECT' :
156 elif occ[1]['FENETRE'] == 'HAMM' :
157 fene=[0.54-0.46*numpy.cos(2*numpy.pi*i1/(l_ech-1)) for i1 in range(l_ech)]
158 elif occ[1]['FENETRE'] == 'HANN' :
159 fene=[0.5-0.5*numpy.cos(2*numpy.pi*i1/(l_ech-1)) for i1 in range(l_ech)]
160 elif occ[1]['FENETRE'] == 'EXPO' :
161 para=occ[1]['DEFI_FENE']
163 raise FonctionError, 'Erreur de taille dans DEFI_FENE : ' + 'la fenetre exponentielle est definie par exactement deux valeurs'
164 fene=[1.]*int(para[0])+[numpy.exp(para[1]*(i1-int(para[0]-1))*dt) for i1 in range(int(para[0]),l_ech)]
165 elif occ[1]['FENETRE'] == 'PART' :
166 fene=occ[1]['DEFI_FENE']
167 if len(fene) != l_ech :
168 raise FonctionError, 'Erreur de taille dans DEFI_FENE : ' + 'La fenetre doit etre definie avec le meme nombre de points que les echantillons'
170 # normalisation de la fenetre
171 fene=numpy.divide(fene,numpy.sqrt(numpy.sum(numpy.multiply(fene,fene)))).tolist()
173 if len(TRANSFERT)+len(INTERSPE) == 0 : #-- on ne rentre rien : interspectre par defaut - fenetre rectangulaire
178 #-- Recuperation des signaux --#
179 #-- Verifications et transformations de Fourier --#
180 #-- Entrees sous formes de table --#
191 if TAB_ECHANT : # Cas TAB_ECHANT
192 num_mes_temp= tab_py['NUME_MES'].values()['NUME_MES']
193 max_mes=numpy.maximum.reduce(num_mes_temp);
194 num_ord_temp= tab_py['NUME_ORDRE_I'].values()['NUME_ORDRE_I']
195 long_fonc=[len(fonc_py[i1].VALE.get()) for i1 in range(len(fonc_py))]
197 N_fen=int(numpy.floor((numpy.minimum.reduce(long_fonc)/2-l_ech)/(l_ech-recouvr))+1)
201 for i1 in range(len(fonc_py)) :
202 vale=fonc_py[i1].VALE.get();
203 temp=(list(vale[0:int(len(vale)/2)]));
204 sig.append(list(vale[int(len(vale)/2):]));
205 test_pas=numpy.subtract(temp[1:],temp[0:-1])
206 crit=test_pas.tolist();
209 if abs((crit[-1]-crit[0])/crit[-1]) > 1.e-5 :
210 raise FonctionError, 'L'+"'"+'echantillonage doit etre fait a pas constant'
212 for j1 in range(N_fen) :
213 for i1 in range(len(fonc_py)) :
214 fft.append(FFT.fft(numpy.multiply(sig[i1][j1*(l_ech-recouvr):(j1*(l_ech-recouvr)+l_ech)],fene)))
215 if j1 == 0 : df.append(1./(dt[i1])/l_ech);
216 num_mes.append(num_mes_temp[i1]+max_mes*j1);
217 num_ord.append(num_ord_temp[i1]);
220 test_df=numpy.subtract(df[1:],df[0:-1])
221 test_df=test_df.tolist();
223 if abs(test_df[-1]) > 1.e-5 :
224 raise FonctionError, 'Toutes les fonctions doivent etre definies ' + 'avec la meme frequence d'+"'"+'echantillonage'
226 frq = [df[-1]*i1 for i1 in range(l_ech)]
229 #-- Recuperation des signaux --#
230 #-- Verifications et transformations de Fourier --#
231 #-- Entrees sous formes de fonction --#
235 vale_sig=occ[1]['FONCTION'].Valeurs();
236 #-- pour les tests ulterieurs --#
237 lt.append(len(vale_sig[0]))
238 if len(vale_sig[0]) != len(vale_sig[1]) :
239 raise FonctionError, 'Les vecteurs associes au temps '+'et aux echantillons doivent etre de meme longueur'
240 num_mes.append(occ[1]['NUME_MES'])
241 num_ord.append(occ[1]['NUME_ORDRE_I'])
243 tmp.append(vale_sig[0])
244 test_pas=numpy.subtract(vale_sig[0][1:],vale_sig[0][0:-1])
245 crit=test_pas.tolist();
247 if abs((crit[-1]-crit[0])/crit[-1]) > 1.e-5 :
248 raise FonctionError, 'L'+"'"+'echantillonage doit etre fait a pas constant'
249 print "vale_sig[1]= ", len(vale_sig[1]), vale_sig[1]
250 print " fene = ",len(fene), fene
251 fft.append(FFT.fft(numpy.multiply(vale_sig[1],fene)))
252 df.append(1./(crit[-1])/len(vale_sig[0]));
255 #-- Verification des longueurs --#
257 test_long=numpy.subtract(lt[1:],lt[0:-1])
258 test_long=test_long.tolist();
260 if (test_long[-1]-test_long[0]) != 0 :
261 raise FonctionError, 'Toutes les fonctions doivent etre definies avec le meme nombre de points'
264 test_df=numpy.subtract(df[1:],df[0:-1])
265 test_df=test_df.tolist();
267 if abs(test_df[-1]) > 1.e-5 :
268 raise FonctionError, 'Toutes les fonctions doivent etre definies '+'avec la meme frequence d'+"'"+'echantillonage'
270 frq = [df[-1]*i1 for i1 in range(lt[-1])]
273 #-- index des numeros d'ordre pour le moyennage
283 list_ord.append(uu[0])
285 for i1 in range(uu.count(uu[0])) :
286 tt.append(vv.index(uu[0]))
289 uu=uu[int(uu.count(uu[0])):]
291 #-- Calcul de la matrice inter spectrale
293 if len(INTERSPE) != 0 :
294 nb_ord = len(list_ord)
295 dimh = (nb_ord*(nb_ord+1))/2
300 for i1 in range(nb_ord) :
301 for j1 in range(i1,nb_ord) :
302 #-- on ne calcule les spectres que pour des numeros de mesures correspondants
303 #-- Ca n'a a priori pas de sens de calculer l'interspectre entre deux signaux acquis a des instants differents
304 #-- Par contre, on peut moyenner deux interspectres obtenus a des instants differents, sous reserve
305 #-- de stationnarite et d'ergodicite du signal
306 mes_i1=[num_mes[k1] for k1 in ind_ord[i1]]
307 mes_j1=[num_mes[k1] for k1 in ind_ord[j1]]
309 #-- recuperation des indices des fft a prendre en compte pour l'interspectre
310 for k1 in range(len(mes_i1)) :
311 if mes_i1[k1] in mes_j1 :
312 ind_mes.append([ind_ord[i1][k1],
313 ind_ord[j1][mes_j1.index(mes_i1[k1])]])
315 #-- Calcul des interspectres
317 if len(ind_mes) > 0 :
318 for l1 in range(len(ind_mes)) :
319 dsp_t=numpy.multiply(numpy.conjugate(fft[ind_mes[l1][0]]),fft[ind_mes[l1][1]])
320 dsp_t=numpy.divide(dsp_t,l_ech*len(ind_mes))
321 dsp=numpy.add(dsp,dsp_t)
325 for k1 in range(int(numpy.floor(l_ech/2))) :
326 dsp_r=dsp_r+[frq[k1],dsp[k1].real,dsp[k1].imag]
328 _fonc = DEFI_FONCTION(NOM_PARA='FREQ',VALE_C=dsp_r,);
329 l_fc.append(_fonc.nom)
330 nume_i1.append(list_ord[i1])
331 nume_j1.append(list_ord[j1])
334 mcfact.append(_F(PARA='NOM_CHAM' ,LISTE_K='DSP' ,NUME_LIGN=(1,) ))
335 mcfact.append(_F(PARA='OPTION' ,LISTE_K='TOUT' ,NUME_LIGN=(1,) ))
336 mcfact.append(_F(PARA='DIMENSION' ,LISTE_I=(dimh,) ,NUME_LIGN=(1,) ))
337 mcfact.append(_F(PARA='NUME_ORDRE_I',LISTE_I=nume_i1 ,NUME_LIGN=range(2,dimh+2) ))
338 mcfact.append(_F(PARA='NUME_ORDRE_J',LISTE_I=nume_j1 ,NUME_LIGN=range(2,dimh+2) ))
339 mcfact.append(_F(PARA='FONCTION_C' ,LISTE_K=l_fc ,NUME_LIGN=range(2,dimh+2)))
340 self.DeclareOut('tab_inte',self.sd)
341 tab_inte=CREA_TABLE(LISTE=mcfact,
343 TYPE_TABLE='TABLE_FONCTION')
348 #-- Calcul des transferts
350 if len(TRANSFERT) != 0 :
356 #-- test sur les entrees pour les references --#
357 if type(l_H[0][1]['REFER'])==int :
359 refer.append(l_H[0][1]['REFER'])
360 elif type(l_H[0][1]['REFER'])==tuple :
361 refer=list(l_H[0][1]['REFER'])
364 dimh = len(refer)*(len(list_ord)-len(refer))
365 for k1 in range(len(refer)) :
366 for l1 in range(len(list_ord)) :
367 if refer[k1] == list_ord[l1] : ind_refer.append(l1);
369 #-- H1 : interspectre / autospectre
370 #-- H2 : autospectre / interspectre
371 #-- CO : coherence entre H1 et H2.
373 if l_H[0][1]['ESTIM']!='HV' :
374 for i1 in range(len(refer)) :
375 for j1 in range(len(list_ord)) :
376 if refer[i1] != list_ord[j1] :
377 mes_i1=[num_mes[k1] for k1 in ind_ord[ind_refer[i1]]] #-- mesures des efforts
378 mes_j1=[num_mes[k1] for k1 in ind_ord[j1]] #-- mesures des reponses
381 #-- recuperation des indices des mesures a predre en compte pour les spectres
382 for k1 in range(len(mes_i1)) :
383 if mes_i1[k1] in mes_j1 :
384 ind_ord[j1][mes_j1.index(mes_i1[k1])]
385 ind_mes.append([ind_ord[ind_refer[i1]][k1],ind_ord[j1][mes_j1.index(mes_i1[k1])]])
391 if len(ind_mes) > 0 :
392 for l1 in range(len(ind_mes)) :
393 Guu_t=numpy.multiply(numpy.conjugate(fft[ind_mes[l1][0]]),fft[ind_mes[l1][0]])
394 Guu=numpy.add(Guu,Guu_t)
395 Gyu_t=numpy.multiply(numpy.conjugate(fft[ind_mes[l1][1]]),fft[ind_mes[l1][0]])
396 Gyu=numpy.add(Gyu,Gyu_t)
397 Gyy_t=numpy.multiply(numpy.conjugate(fft[ind_mes[l1][1]]),fft[ind_mes[l1][1]])
398 Gyy=numpy.add(Gyy,Gyy_t)
400 if l_H[0][1]['ESTIM']=='H1' :
401 frf=numpy.divide(numpy.conjugate(Gyu),Guu);
403 elif l_H[0][1]['ESTIM']=='H2' :
404 frf=numpy.divide(Gyy,Gyu);
406 elif l_H[0][1]['ESTIM']=='CO' :
407 H1=numpy.divide(numpy.conjugate(Gyu),Guu);
408 H2=numpy.divide(Gyy,Gyu);
409 frf=numpy.divide(H1,H2);
415 for k1 in range(int(numpy.floor(l_ech/2))) :
416 frf_r=frf_r+[frq[k1],frf[k1].real,frf[k1].imag]
418 _fonc = DEFI_FONCTION(NOM_PARA='FREQ',VALE_C=frf_r,);
419 l_fc.append(_fonc.nom)
420 nume_i1.append(refer[i1])
421 nume_j1.append(list_ord[j1])
423 #-- On remplit la table_fonction avec tout ce qui va bien
426 mcfact.append(_F(PARA='NOM_CHAM' ,LISTE_K=nom_frf ))
427 mcfact.append(_F(PARA='OPTION' ,LISTE_K='TOUT' ))
428 mcfact.append(_F(PARA='DIMENSION' ,LISTE_I=(dimh,) ))
429 mcfact.append(_F(PARA='NUME_ORDRE_I',LISTE_I=nume_i1 ))
430 mcfact.append(_F(PARA='NUME_ORDRE_J',LISTE_I=nume_j1 ))
431 mcfact.append(_F(PARA='FONCTION_C' ,LISTE_K=l_fc ))
432 self.DeclareOut('tab_inte',self.sd)
433 tab_inte=CREA_TABLE(LISTE=mcfact,
435 TYPE_TABLE='TABLE_FONCTION')