; La lecture de ce programme se fait de bas en haut: ; 1) xncdf_lec ; -->2) xncdf_lec_event ; |--> 3) wid_var ; --> wid_var_event ; pro wid_var_event, event ; NAME:wid_var_event ; ; PURPOSE:procedure appele par xmanager qd on appuie sur un bouton du ; 2eme widget cree par wid_var ; ; INPUTS: event, une structure caracterisant le type d''evenement qui ; arrive au widget numero1 2 ; ; COMMON BLOCKS:wididbase,resultat,infovariable,indicewid,motcle ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ COMMON wididbase, base COMMON resultat, res COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient COMMON indicewid_var, widbase1, widbase2111, widbase212, widbase213, selectatt COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar ; ; quel est le type d''evenement? widget_control, event.id, get_uvalue=uval tailledimvar = tailledim[varcontient.dim] if n_elements(uval) EQ 0 then return ; case sur le type d''evenement case uval OF 1:BEGIN ; on change des valeurs dans le tableau ; on controle que les valeurs mises dans le tableau ne sont pas ; completement fausses widget_control, widbase1, get_value = table ; agument du bon type ? ; si le type est mauvais on change automatiquement par des valeurs par ; defaut if event.x GT (size(table))[1] then return if event.y GT (size(table))[2] then return if size(table[event.x, event.y], /type) GE 6 $ OR size(table[event.x, event.y], /type) EQ 0 then BEGIN if event.x EQ 1 then $ widget_control, widbase1, use_table_select = [1, event.y,1, event.y] $ , set_value = tailledimvar[event.y] $ ELSE widget_control, widbase1 $ , use_table_select = [event.x, event.y, event.x, event.y], set_value = 0 endif ; agument avec une valeur nom debile? table = fix(table) case event.x of 0:BEGIN ; on a touche a l''offset: if table[0, event.y] LT 0 then BEGIN table[0, event.y] = 0 widget_control, widbase1, use_table_select = [0, event.y, 0, event.y] $ , set_value = 0 endif ; si il depasse la dim du tableau on le met au max et le cont a 1 if table[0, event.y] GT tailledimvar[event.y]/table[3, event.y] then begin widget_control, widbase1, use_table_select = [0, event.y,1, event.y] $ , set_value = [tailledimvar[event.y]/table[3, event.y], 1] ENDIF ELSE BEGIN ; si avec le nouvel offset le count est trop grand, on le diminue juste ; de ce qu''il faut! if table[1, event.y] GT $ (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] then begin widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $ , set_value = (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] endif ENDELSE END 1:BEGIN ;on a touche au count if table[1, event.y] LT 1 then BEGIN table[1, event.y] = 1 widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $ , set_value = 1 endif ; si il est trop grand, on le diminue juste de ce qu''il faut! if table[1, event.y] GT $ (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] then BEGIN widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $ , set_value = (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] endif END 2:BEGIN ; on a touche au shift widget_control, widbase1, use_table_select = [2, event.y, 2, event.y] $ , set_value = table[2, event.y] MOD (tailledimvar[event.y]/table[3, event.y]) END 3:BEGIN ; on touche au stride if table[3, event.y] LT 1 then BEGIN table[3, event.y] = 1 widget_control, widbase1, use_table_select = [3, event.y, 3, event.y] $ , set_value = 1 endif if table[3, event.y] EQ 0 then $ ; il ne doit pas etre nul widget_control, widbase1, use_table_select = [3, event.y, 3, event.y] $ , set_value = 1 ; il ne doit pas etre trop grand if table[3, event.y] GT tailledimvar[event.y] then $ widget_control, widbase1, use_table_select = [0, event.y,3, event.y] $ , set_value = [0, 1, 0, tailledimvar[event.y]] $ ELSE BEGIN if table[1, event.y] GT $ (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] then begin widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $ , set_value = (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] endif ENDELSE END ELSE: endcase END 2111:BEGIN ;on a touche aux boutons oui/non ; on actualise le vecteur selectatt a 0 ou 1 pour l''attribut concerne ; (numero event.id) selectatt[where(widbase2111 EQ event.id)] = event.select end 31:BEGIN ;on a appuye sur 'get' widget_control, widbase1, get_value = table table = fix(table) mcshift = where(table[2, *] NE 0) mcoffset = table[0, *] mccount = table[1, *] mcstride = table[3, *] if mcshift[0] NE -1 then BEGIN ; il y a des shifts ; on lit l''integralite des dimensions pour lesquelles il y a un shift mcoffset[mcshift] = 0 mccount[mcshift] = tailledimvar[mcshift] ; on active pas stride qd il n''y en a pas besoin car ca fait ecrire a ; l''ecran qqch de louche... if total(mcstride) EQ n_elements(mcstride) then $ ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount $ ELSE $ ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount, STRIDE = mcstride ; pour faire le shift mcshift = table[2, *] mcoffset = table[0, *] mccount = table[1, *] ; on definit commende qui permet de faire un shift commande = 'res=shift(res' for dim = 0, varcontient.ndims-1 do commande = commande+','+string(table[2,dim]) commande = commande+')' rien = execute(commande) ; on redefinit commnade qui permet de couper les dimensions qui n''ont ; pas ete encore coupees (c''est celles que l''on shift) commande = 'res=res[' ; initialisation de la commende for dim = 0, varcontient.ndims-1 do BEGIN if mcshift[dim] EQ 0 then commande = commande+'*,' $ ELSE commande=commande+string(mcoffset[dim])+':'+string(mccount[dim]+mcoffset[dim]-1)+',' ENDFOR commande = strmid(commande, 0, strlen(commande)-1)+']' rien = execute(commande) ; cas sans shift, on lit directement le bon bout de tableau ENDIF ELSE BEGIN if total(mcstride) EQ n_elements(mcstride) then $ ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount $ ELSE $ ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount, STRIDE = mcstride ENDELSE ; faut-il constituer une structure avec les attributs qui on ete selectionnes if total(selectatt) NE 0 then BEGIN ; il y a des attributs selectionnes res = create_struct(varcontient.name, res) ; on cree la structure selectatt = where(selectatt EQ 1) ; on trouve les attributs selectiones for attid = 0, n_elements(selectatt)-1 do BEGIN ; pour lesquels on prend widget_control, widbase212[selectatt[attid]], get_value = attname ; le nom widget_control, widbase213[selectatt[attid]], get_value = attvalue ; la valeur res = create_struct(res, attname[0], attvalue[0]) ; on concatene la structe endfor endif widget_control, event.top, /destroy ;on ferme le 2eme widget widget_control, base, /destroy ;on ferme le 1eme widget ncdf_close,cdfid END 32: ;cas de l''affichage d''un held (avec xdisplayfile) 33:widget_control, event.top, /destroy ;on ferme le 2eme widget ELSE: endcase return end ;------------------------------------------------------------ ;------------------------------------------------------------ PRO wid_var, widid_pere ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ ; NAME: wid_var ; ; PURPOSE: cette procedure gere le 2eme widget cree qd on appelle ; xncdf_lec. ce widget concerne la lecture de la variable ; ; INPUTS: widid_pere: un scalere contenant l'identite du widget pere ; qui a etait cree par xncdf_lec et qui a permis de selectionner la ; variable a lire. ; ; OUTPUTS: indirectement res (le tableau ou la structure resultat) ; ; COMMON BLOCKS:resultat,infovariable,indicewid_var,motcle ; ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ COMMON resultat, res COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient COMMON indicewid_var, widbase1, widbase2111, widbase212, widbase213, selectatt COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar res = -1 ;------------------------------------------------------------ ; ouverture de la fenetre de base sous forme de colonnes ;------------------------------------------------------------ widbase = widget_base(/column, title='variable: '+varcontient.name, /align_center, group_leader = widid_pere) ;------------------------------------------------------------ ; ouverture de sous-fenetres de base ; ;------------------------------------------------------------ ; widbase1 tableau des offsets ;------------------------------------------------------------ rien = widget_label(widbase, value = ' ') ; on saute une ligne ; defintion des lables des lignes du tableau rowlab = string(tailledim[varcontient.dim]) for i = 0, n_elements(rowlab)-1 do rowlab[i] = strtrim(rowlab[i], 1) rowlab = nomdim[varcontient.dim]+replicate(': ', n_elements(varcontient.dim))+rowlab ; definition des valeurs initiales du tableau valinit = lonarr(4, n_elements(varcontient.dim)) ; colonne 0 : les offset if keyword_set(mcoffset) AND n_elements(mcoffset) EQ varcontient.ndims THEN $ valinit[0,*]=mcoffset ELSE valinit[0, *] = 0 ; colonne 1 : les counts if keyword_set(mccount) AND n_elements(mccount) EQ varcontient.ndims THEN $ valinit[1,*]=mccount ELSE valinit[1, *] = tailledim[varcontient.dim] ; colonne 2 : les shifts if keyword_set(mcshift) AND n_elements(mcshift) EQ varcontient.ndims THEN $ valinit[2,*]=mcshift ELSE valinit[2, *] = 0 ; colonne 3 : les strides if keyword_set(mcstride) AND n_elements(mcstride) EQ varcontient.ndims THEN $ valinit[3,*]=mcstride ELSE valinit[3, *] = 1 ; test des valeurs initiales du tableau valinit = fix(valinit) valinit[3, *] = 1 > valinit[3, *] < tailledim[varcontient.dim] ; test des strides valinit[0, *] = 0 > valinit[0, *] < tailledim[varcontient.dim] ; test des offsets ; test des counts valinit[1, *] = 1 > valinit[1, *] < ((tailledim[varcontient.dim]/valinit[3, *])-valinit[0, *]) valinit[2, *] = valinit[2, *] MOD (tailledim[varcontient.dim]/valinit[3, *]) ; test des shifts ; declaration du tableau widbase1 = widget_table(widbase, row_labels = rowlab, value = valinit, /editable $ , column_labels = ['Offset', 'Count', 'Shift', 'Stride'], uvalue = 1) ; un petit blabla rien = widget_label(widbase, value = 'ATTENTION: Faire des ''return'' pour que les valeurs', /align_center) rien = widget_label(widbase, value = 'du tableau ou des textes soient bien prises en compte', /align_center) ;------------------------------------------------------------ ; widbase2 choix des attributs ;------------------------------------------------------------ rien = widget_label(widbase, value = ' ') ; on saute une ligne widbase2 = widget_base(widbase, /column) ; pour chaque attribut, on cree un widget (widbase21) qui contient en ligne un ; bouton oui/non (widbase211), et deux wigdet text (widbase212, ; widbase213)comportant le nom et la valeur de l''attribut. widbase21 = lonarr(varcontient.natts) widbase211 = lonarr(varcontient.natts) widbase2111 = lonarr(varcontient.natts) ; vecteur qui serviera a savoir quels boutons oui/non sont ; selectiones. cf. wid_var_event selectatt = lonarr(varcontient.natts) selectatt[*] = 0 widbase212 = lonarr(varcontient.natts) widbase213 = lonarr(varcontient.natts) for attid = 0, varcontient.natts-1 do BEGIN ;boucle sur le nombre d''attributs widbase21[attid] = widget_base(widbase2, /row) name=ncdf_attname(cdfid,varid,attid) ncdf_attget,cdfid,varid,name,value widbase211[attid] = widget_base(widbase21[attid], /nonexclusive) widbase2111[attid] = widget_button(widbase211[attid], value = ' ', uvalue = 2111) widbase212[attid] = widget_text(widbase21[attid], value = name, /editable) widbase213[attid] = widget_text(widbase21[attid], value=strtrim(string(value),1), /editable) endfor ;------------------------------------------------------------ ; widbase3 boutons du bas ;------------------------------------------------------------ widbase3 = widget_base(widbase, /row,/align_center) widbase31=widget_button(widbase3,value='GET', uvalue=31) widbase32=widget_button(widbase3,value='Help', uvalue=32) widbase33=widget_button(widbase3,value='DONE', uvalue=33) ;------------------------------------------------------------ ;execution de la fentre de base et des sous-fenetres ;------------------------------------------------------------ widget_control,widbase,/realize ;------------------------------------------------------------ xmanager,'wid_var',widbase return end ;------------------------------------------------------------ PRO xncdf_lec_event, event ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ ; NAME:xncdf_lec_event ; ; PURPOSE: procedure appele par xmanager qd on appuie sur un bouton du ; 1ere widget cree par xncdf_lec ; ; INPUTS: event, une structure caracterisant le type d''evenement qui ; arrive au widget numero1 ; ; COMMON BLOCKS:resultat, infovariable, motcle ; ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ COMMON resultat, res COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar ; quel est le type d''evenement? widget_control, event.id, get_uvalue=uval ; case sur le type d''evenement case uval of 1:BEGIN ; on veut lire un autre fichier widget_control, event.id, get_value = nom ; on recupere le nom widget_control, event.top, /destroy ;on ferme le widget ncdf_close,cdfid ; on ferme le mauvais fichier qui a ete ouvert ; on reapelle xncdf_lec res = xncdf_lec(nom[0], ATT = mcatt, COUNT = mccount, OFFSET = mcoffset, IODIR = mciodir $ , SHIFT = mcshift, STRIDE = mcstride, VAR = mcvar) return END 2:BEGIN ; une variable est selectionee varid = event.index ; on recupere son numero ds le fichier Netcdf varcontient = ncdf_varinq(cdfid,varid) wid_var, event.top ; on appelle le programme qui lance le 2eme widget. cf. + haut END 3:BEGIN ; bouton done widget_control, event.top, /destroy ; on tue le widget ncdf_close,cdfid ; on ferme le fichier END ELSE: endcase return end ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ ;+ ; NAME: xncdf_lec ; ; PURPOSE: lecture d''un fichier Net Cdf avec des widgets ! ; ; CATEGORY: lecture de fichiers avec widgets ; ; CALLING SEQUENCE: res=xncdf_lec([nom_fichier]) ; ; INPUTS: ; OPTIONNEL, nom_fichier: c''est un string qui donne le nom du ; fichier a ouvrir.Si nomfichier ne contient pas le caractere ; separateur de repertoirte ('/' sous unix par ex), Le fichier ; sera cherche ds le repertoire courant ; ; KEYWORD PARAMETERS: ; ; IODIR: string contenant le repertoire ou aller chercher le ; fichier a lire. Si nomfichier ne contient pas le caractere ; separateur de repertoirte ('/' sous unix par ex), Le fichier ; cherche s''appelera iodir+nom_fichier. ; ; COUNT: An optional vector containing the counts to be used in ; reading Value. COUNT is a 1-based vector with an element for ; each dimension of the data to be written.The default matches ; the size of the variable so that all data is written out. ; ; GROUP: The widget ID of the widget that calls XNCDF_LEC. When ; this ID is specified, a death of the caller results in a death ; of XNCDF_LEC. ; ; OFFSET: An optional vector containing the starting position ; for the read. The default start position is [0, 0, ...]. ; ; SHIFT: un vecteur d''entiers, specifiant pour chaque dimension ; de combien il faut la shifter. Par defaut c''est ; [0,0,...]. cf. la fonction shift pour + ; d''explications. ATTENTION, le shift est effectue sur le ; tableau de taille maximum avant la reduction eventuelle ; determinee par OFFSET et COUNT. Par contre il est effectue ; apres l''extraction eventuelle cree par le STRIDE. ; ; STRIDE: An optional vector containing the strides, or sampling ; intervals, between accessed values of the netCDF variable. The ; default stride vector is that for a contiguous read, [1, 1, ; ...]. ; ; OUTPUTS: 2 cas possibles: ; 1) aucun attributs n''a ete selectionne. Dans ce cas res est ; le tableau que l''on voulait lire. ; 2) Des attributs ont ete selectionnes. Dans ce cas res est une ; structre dont le premier element portant le nom de la variable ; est le tableau de valeurs et les autre auguments sont les ; arguments selectiones ; ; COMMON BLOCKS: wididbase, infovariable, resultat, motcle ; ; SIDE EFFECTS: ; ; RESTRICTIONS: ; ; EXAMPLE: help, xncdf_lec() ; ; MODIFICATION HISTORY:Sebastien Masson (smasson@lodyc.jussieu.fr) ; 24/8/1999 ;- ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ FUNCTION xncdf_lec, nom, ATT = att, COUNT = count, GROUP = group, OFFSET = offset, IODIR = iodir, SHIFT = shift, STRIDE = stride, VAR = var COMMON wididbase, base COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient COMMON resultat, res COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar ;------------------------------------------------------------ ; bidouille pour utiliser les mots cles (on passe par des variables ; declarees ds un common) ;------------------------------------------------------------ res = -1 if keyword_set(att) then mcatt = att ELSE mcatt = 0 if keyword_set(count) then mccount =count ELSE mccount = 0 if keyword_set(offset) then mcoffset = offset ELSE mcoffset = 0 if keyword_set(shift) then mcshift = shift ELSE mcshift = 0 if keyword_set(stride) then mcstride = stride ELSE mcstride = 0 if keyword_set(var) then mcvar = var ELSE mcvar = 0 ;------------------------------------------------------------ ; choix du nom du fichier ;------------------------------------------------------------ ; Quel type de machine est utiliee thisOS = strupcase(strmid(!version.os_family, 0, 3)) CASE thisOS of 'MAC':sep = ':' 'WIN':sep = '\' ELSE: sep = '/' ENDCASE ; si iodir n''est pas definit on l''initialise au repertoire courant if NOT keyword_set(iodir) then cd, current = iodir mciodir = iodir ; on complete iodir d''un caractere separateur de repertoire si besoin ; est. IF rstrpos(iodir, sep) NE strlen(iodir)-1 THEN iodir = iodir+sep if n_elements(nom) EQ 0 then BEGIN ; si nom n''est pas definit ; on en trouve un grace au programme dialog_pickfile nom = dialog_pickfile(filter = iodir+'*.nc') if nom[0] EQ '' then return, -1 ; si on a rien trouve on sort ;on complete nom par iodir si nom ne contient pas de caractere ;separateur derepertoire ENDIF ELSE if strpos(nom, sep) EQ -1 then nom = iodir+nom test = findfile(nom) ; le nom cherche correspond bien a un fichier? while test[0] EQ '' OR n_elements(test) GT 1 do BEGIN ; on en cherche un tant qu''il ne correspond a rien! test = test[0] nom = dialog_pickfile(filter = iodir+'*.nc') if nom EQ '' then return, -1 test = findfile(nom) endwhile ;------------------------------------------------------------ ; ouverture du fichier nom ;------------------------------------------------------------ cdfid=ncdf_open(nom) contient=ncdf_inquire(cdfid) ;------------------------------------------------------------ ; que contient le fichier?? ;------------------------------------------------------------ ; ouverture de la fenetre de base sous forme de colonnes if n_elements(group) EQ 0 then base = widget_base(/column, title='Fichier: '+nom, /align_left) $ ELSE base = widget_base(/column, title='Fichier: '+nom, /align_left, GROUP_LEADER = group) ; ouverture de sous-fenetres de base ; ;------------------------------------------------------------ ; base 1 titre portant le nom du fichier ;------------------------------------------------------------ base1 = widget_base(base, /column, /align_center) rien = widget_label(base1, value = 'Net Cdf filename', /align_center) ; blabla rien = widget_text(base1, value = nom, /align_center, uvalue=1, /editable) ;nom du fichier que l''on peut changer rien = widget_label(base1, value = ' ') ; on saute une ligne ;------------------------------------------------------------ ; base 2 informations generales sur le fichier ;------------------------------------------------------------ base2 = widget_base(base, /column) ;------------------------------------------------------------ ; informations sur les attributs globaux ;------------------------------------------------------------ if contient.ngatts NE -1 then begin rien = widget_label(base2, value = 'Nombre de attributs globaux: '+ strtrim(contient.ngatts,1), /align_left) for attiq=0,contient.ngatts-1 do BEGIN ; bouble sur le nombre d'attributs globaux name=ncdf_attname(cdfid,attiq,/global) ;nom de l''atribut ncdf_attget,cdfid,name,value,/global ;valeur de l''atribut rien = widget_text(base2, value = name+': '+strtrim(string(value),1), xsize = 60, /scroll, /wrap, /align_right) endfor rien = widget_label(base2, value = ' ') endif ;------------------------------------------------------------ ; informations sur les dimensions ;------------------------------------------------------------ rien = widget_label(base2, value = 'Nombre de dimensions: '+strtrim(contient.ndims,1), /align_left) if contient.recdim NE -1 then begin ; bouble sur le nombre de dimensions ncdf_diminq,cdfid,contient.recdim,name,value ; nom et valeur de la dimension rien = widget_label(base2, value = 'nom de la dimension infinie: '+name, /align_left) endif ; nomdim =strarr(contient.ndims) ; vecteur contenant le nom des dimensions tailledim=lonarr(contient.ndims) ; vecteur contenant la valeur des dimensions for dimiq=0,contient.ndims-1 do begin ; bouble sur le nombre de dimensions ncdf_diminq,cdfid,dimiq,name,value ; nom et valeur de la dimension nomdim[dimiq]=name tailledim[dimiq]=value rien = widget_label(base2, value = name+' de taille: '+strtrim(value,1), /align_right) ENDFOR rien = widget_label(base2, value = ' ') ; on saute une ligne ;------------------------------------------------------------ ; base 3 choix de la variable ;------------------------------------------------------------ base3 = widget_base(base, /column) rien = widget_label(base3, value = 'Nombre de variables: '+strtrim(contient.nvars,1), /align_left) base31 = widget_base(base3, /row, /align_center) ;creation d'un vecteur listename contenant le nom de toutes les ;variables du fichier listename = strarr(contient.nvars) for varid=0,contient.nvars-1 do begin varcontient=ncdf_varinq(cdfid,varid) ; que contient la variable listename[varid] = varcontient.name endfor rien= widget_label(base31, value = 'variable') ; creation d''un bouton a menu deroulant base311=widget_droplist(base31,value=listename, uvalue=2) rien = widget_label(base3, value = '') ;------------------------------------------------------------ ; base 4 bouton done ;------------------------------------------------------------ base4 = widget_base(base, /row) base42=widget_button(base4,value='done', uvalue=3, /align_right) ;execution de la fentre de base et des sous-fenetres widget_control,base,/realize ;------------------------------------------------------------ xmanager,'xncdf_lec',base ;------------------------------------------------------------ ;------------------------------------------------------------ ;------------------------------------------------------------ return, res end