;+ ; ; @categories ; ; @examples ; ncdf_extrait,nomfich1,nomfich2 [,domaine] ; ; @param NOMFICH1 {in}{required} ; le nom du fichier d'entree ; ; @param NOMFICH2 {in}{required} ; le nom du fichier de sortie ; ; @param DOMAINE {in}{optional} ; un vecteur de chaines de chatacteres qui permet de ; definir les dimensions a extraire. sa forme doit etre la ; suivante: ; ['nomdim1,indiceinf1,indicesup1','nomdim2,indiceinf2,indicesup2',...] ; rq: seules les dimensions a reduire doivent etre specifiees ; les dimensions ne figurant pas ds domaine seront selectionnees ds leur integralite. ; ; @param NOMFICH2 {out} ; ; @keyword GARDE ; vecteur donnant les noms des variables a ; selectionner. si il n'est pas active toutes les variables ; sont selectionnees. ; ; @keyword EXCLU ; vecteur donnant les noms des variablers a ne pas ; selectionner. si il n'est pas active toutes les variables ; sont selectionnees. ; ; @uses ; common.pro ; ; @restrictions ; ce programme ne marche que si les tableaux sont de ; dimension inferieure ou egale a 4. ; ATTENTION: AVANT DE CREER LE FICHIER NET-CDF, ; S'ASSURER QU'IL Y A DE LA PLACE DS LE REPERTOIRE POUR LE FAIRE SINON ; LE PROGRAMME PLANTE LORS DE L'ECRITURE DU FICHIER ET DONNE UNE ; INDICATION BIDON... ; ; @examples ; ; @history ; Sebastien Masson (smasson\@lodyc.jussieu.fr) ; 20/11/98 ; 13/1/98 : attribut concernant le min et le max ; 18/1/98 : bug qd ont fait disparaitre une dimension (sa taille ; devenant =1) ;- PRO ncdf_extrait, nomfich1, nomfich2, domaine, GARDE = garde, EXCLU = exclu ;------------------------------------------------------------ ; contenu de nomfich1 ;------------------------------------------------------------ cdfid1 = ncdf_open(nomfich1) contient1 = ncdf_inquire(cdfid1) ;------------------------------------------------------------ ; decripter domaine s'il y en a un ;------------------------------------------------------------ case n_params() of 2:domaine = ['rien, 0,0'] 3: ELSE: endcase taille = n_elements(domaine) nomdim = strarr(taille[0]) indiceinf = lonarr(taille[0]) indicesup = lonarr(taille[0]) for i = 0, taille[0]-1 do begin separe = str_sep(domaine[i], ',') nomdim[i] = strlowcase(strtrim(separe[0], 2)) indiceinf[i] = long(separe[1]) indicesup[i] = long(separe[2]) endfor ;------------------------------------------------------------ ; mise en place du resultat ;------------------------------------------------------------ cdfid2 = ncdf_create('travaille.nc', /clobber) ;------------------------------------------------------------ ; dimensions qui vont rester ;------------------------------------------------------------ nomdim1 = strarr(contient1.ndims) tailledim1 = lonarr(contient1.ndims) tailledim2 = lonarr(contient1.ndims) indiceinf2 = lonarr(contient1.ndims) indicesup2 = lonarr(contient1.ndims) gardedim = lonarr(contient1.ndims) for dimid = 0,contient1.ndims-1 do begin ncdf_diminq, cdfid1, dimid, name, value nomdim1[dimid] = name tailledim1[dimid] = value pos = where(nomdim EQ strlowcase(name), count) if count NE 0 then BEGIN ; si c'est une dim a reduire tailledim2[dimid] = indicesup[pos]-indiceinf[pos]+1 indicesup2[dimid] = indicesup[pos] indiceinf2[dimid] = indiceinf[pos] ; dim degeneree ? IF tailledim2[dimid] EQ 1 THEN gardedim[dimid] = 0 ELSE gardedim[dimid] = 1 ENDIF ELSE BEGIN tailledim2[dimid] = tailledim1[dimid] indicesup2[dimid] = tailledim1[dimid]-1 indiceinf2[dimid] = 0 gardedim[dimid] = 1 ENDELSE endfor reduit = where(gardedim EQ 1, nbredim2) if reduit[0] NE -1 then begin tailledim2 = tailledim2(reduit) nomdim2 = nomdim1(reduit) ;------------------------------------------------------------ ; definition des dimensions du nouveau fichier ;------------------------------------------------------------ dimid2 = lonarr(nbredim2) for i = 0,nbredim2-1 do begin if nomdim2[i] NE nomdim1[contient1.recdim] then $ dimid2[i] = ncdf_dimdef(cdfid2, nomdim2[i], tailledim2[i]) $ ELSE dimid2[i] = ncdf_dimdef(cdfid2, nomdim2[i], /unlimited) endfor endif ; ; on recupere l''id, pour le fichier de sortie, des dimensions a garder. ; pour cela on construit indice qui est la liste des dimensions a ; garder et leurs indices ds nomdim2. ; if contient1.recdim NE -1 then $ ; si la dim infinie existe ds le fichier d''entree if gardedim[contient1.recdim] NE 0 then begin ; si la dim infinie existe ds le fichier de sortie case 1 of nomdim2[0] EQ nomdim1[contient1.recdim]:renverser = 1 nomdim2[n_elements(nomdim2)-1] EQ nomdim1[contient1.recdim]:renverser = 0 ELSE: BEGIN print, 'la dimension infinie doit etre la premiere ou la derniere des dimensions du tableau' stop end endcase endif ;------------------------------------------------------------ ; definitions des attributs globeaux du nouveau fichier ;------------------------------------------------------------ for attiq = 0, contient1.ngatts-1 do begin name=ncdf_attname(cdfid1,attiq,/global) rien = ncdf_attcopy(cdfid1,name,cdfid2,/in_global, /out_global) endfor ;------------------------------------------------------------ ; definition des variables ;------------------------------------------------------------ varid2 = lonarr(contient1.nvars) for i = 0,contient1.nvars-1 do begin varcontient = ncdf_varinq(cdfid1, i) case 1 of keyword_set(GARDE):rien = where(strlowcase(garde) EQ strlowcase(varcontient.name), test) keyword_set(EXCLU):BEGIN rien = where(strlowcase(exclu) EQ strlowcase(varcontient.name), test) test = 1-test END ELSE :test = 1 endcase if test EQ 1 then begin IF total(gardedim(varcontient.dim)) NE 0 THEN BEGIN ; la variable extraite n'est pas un scalaire ; ; attention au cas ou l''on a des dim qui on disparuent, il faut ; verifier si elles sont presentes ds varcontient.dim et les enlever ; au besoin. ; varcontientvraidim = varcontient.dim[where(gardedim[varcontient.dim] eq 1)] indice = -1 for ii = 0, n_elements(nomdim2)-1 do begin if total(nomdim2[ii] EQ nomdim1[varcontientvraidim]) NE 0 then $ indice = [indice, ii] ENDFOR indice = indice[1:n_elements(indice)-1 ] if renverser EQ 1 then indice = reverse(indice) commande = 'varid2[i] = ncdf_vardef(cdfid2, varcontient.name, dimid2(indice),'+varcontient.datatype+'=1)' rien = execute(commande) ENDIF ELSE BEGIN commande = 'varid2[i] = ncdf_vardef(cdfid2, varcontient.name,'+varcontient.datatype+'=1)' rien = execute(commande) ENDELSE ;------------------------------------------------------------ ; atributs des variables ;------------------------------------------------------------ FOR attid = 0,varcontient.natts-1 do begin name = ncdf_attname(cdfid1,i , attid) case 1 of strpos(name, 'max') ne -1:BEGIN ncdf_attput,cdfid2,varcontient.name, 'valid_max', '-0.0000000e+00f' maxexiste = 1 END strpos(name, 'min') ne -1:BEGIN ncdf_attput,cdfid2,varcontient.name, 'valid_min', '-0.0000000e+00f' minexiste = 1 END ELSE:bidon = ncdf_attcopy(cdfid1,varcontient.name , name, cdfid2,varcontient.name) endcase if n_elements(maxexiste) EQ 0 then ncdf_attput,cdfid2,varcontient.name, 'valid_max', '-0.0000000e+00f' if n_elements(minexiste) EQ 0 then ncdf_attput,cdfid2,varcontient.name, 'valid_min', '-0.0000000e+00f' endfor endif endfor ;------------------------------------------------------------ ; fin de la definition du fichier de sortie. ;------------------------------------------------------------ ncdf_control, cdfid2, /endef ;------------------------------------------------------------ ; debut du remplissage des variables ;------------------------------------------------------------ for i = 0,contient1.nvars-1 do begin varcontient = ncdf_varinq(cdfid1, i) case 1 of keyword_set(GARDE):rien = where(strlowcase(garde) EQ strlowcase(varcontient.name), test) keyword_set(EXCLU):BEGIN rien = where(strlowcase(exclu) EQ strlowcase(varcontient.name), test) test = 1-test END ELSE :test = 1 endcase if test EQ 1 then begin print, varcontient.name ; case n_elements(varcontient.dim[where(gardedim[varcontient.dim] eq 1)]) of case varcontient.ndims of 0:BEGIN ncdf_varget, cdfid1, varcontient.name, tab ncdf_varput, cdfid2, varcontient.name,tab end 1:BEGIN count = [indicesup2(varcontient.dim[0])-indiceinf2(varcontient.dim[0])+1] ncdf_varget, cdfid1, i, tab, $ offset = [indiceinf2(varcontient.dim[0])], $ count = count ncdf_varput, cdfid2, varcontient.name,tab end 2:BEGIN count = [indicesup2(varcontient.dim[0])-indiceinf2(varcontient.dim[0])+1 $ ,indicesup2(varcontient.dim[1])-indiceinf2(varcontient.dim[1])+1 ] ncdf_varget, cdfid1, i, tab, $ offset = [indiceinf2(varcontient.dim[0]),indiceinf2(varcontient.dim[1])], $ count = count test = where(count[0] EQ 1) IF test[0] NE -1 THEN tab = reform(tab) ncdf_varput, cdfid2, varcontient.name,tab end 3:BEGIN count = [indicesup2(varcontient.dim[0])-indiceinf2(varcontient.dim[0])+1 $ ,indicesup2(varcontient.dim[1])-indiceinf2(varcontient.dim[1])+1 $ ,indicesup2(varcontient.dim[2])-indiceinf2(varcontient.dim[2])+1 ] ncdf_varget, cdfid1, i, tab, $ offset = [indiceinf2(varcontient.dim[0]),indiceinf2(varcontient.dim[1]) $ ,indiceinf2(varcontient.dim[2])], $ count = count test = where(count[0:1] EQ 1) IF test[0] NE -1 THEN tab = reform(tab) ncdf_varput, cdfid2, varcontient.name,tab end 4:BEGIN count = [indicesup2(varcontient.dim[0])-indiceinf2(varcontient.dim[0])+1 $ ,indicesup2(varcontient.dim[1])-indiceinf2(varcontient.dim[1])+1 $ ,indicesup2(varcontient.dim[2])-indiceinf2(varcontient.dim[2])+1 $ ,indicesup2(varcontient.dim[3])-indiceinf2(varcontient.dim[3])+1 ] ncdf_varget, cdfid1, i, tab, $ offset = [indiceinf2(varcontient.dim[0]),indiceinf2(varcontient.dim[1]) $ ,indiceinf2(varcontient.dim[2]),indiceinf2(varcontient.dim[3])], $ count = count test = where(count[0:2] EQ 1) IF test[0] NE -1 THEN tab = reform(tab) ncdf_varput, cdfid2, varcontient.name,tab end ELSE: endcase ;------------------------------------------------------------ ; mise a jour du min et du max de la variable ;------------------------------------------------------------ ; recherche de la missing value de l'argument max et min ... FOR attid = 0,varcontient.natts-1 do begin name = ncdf_attname(cdfid1,i , attid) if strpos(strlowcase(name), 'missing') ne -1 then BEGIN ncdf_attget, cdfid1,i ,name , value ; la missing value existe ?? missing = float(string(value)) endif endfor if n_elements(missing) NE 0 then BEGIN ; test different suivant la valeure if abs(missing) LT 1e6 then BEGIN ; de missing pour eviter les erreures nomask = where(tab NE missing) ; d''arondis... max = max(tab[nomask], min = min) ENDIF ELSE BEGIN nomask = where(abs(tab) LT abs(missing)/10.) max = max(tab[nomask], min = min) ENDELSE nomask = 1 ENDIF ELSE max = max(tab, min = min) ncdf_attput,cdfid2,varcontient.name, 'valid_max', strtrim(max, 2)+'f' ncdf_attput,cdfid2,varcontient.name, 'valid_min', strtrim(min, 2)+'f' tempvar = SIZE(TEMPORARY(min)) ; pour effacer le min tempvar = SIZE(TEMPORARY(max)) ; pour effacer le max tab = 1 endif endfor ;------------------------------------------------------------ ; fermeture des fichiers ;------------------------------------------------------------ ncdf_close, cdfid1 ncdf_close, cdfid2 ;------------------------------------------------------------ ; changement de nom du fichier de resultat ;------------------------------------------------------------ commande = 'mv travaille.nc '+nomfich2 spawn, commande ;------------------------------------------------------------ return end