source: trunk/SRC/ToBeReviewed/LECTURE/xncdf_lec.pro @ 378

Last change on this file since 378 was 378, checked in by pinsard, 16 years ago

improvements of headers (typo, links, paragraphes, etc)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 24.2 KB
Line 
1;+
2;
3; @file_comments
4; Reading of a NetCdf file with widgets
5;
6; @categories
7; Widget
8;
9; @param NAME {in}{optional}{type=string}
10; It give the name of the file to be opened.
11;
12; If NAME
13; does not contain the separating character of directories ('/' under
14; unix for example), the file will be looked for in the current directory.
15;
16; @keyword IODIR {type=string}
17; It contains the directory where to go look for the file to be read.
18;
19; If NAME does not contain the separating character of directories ('/' under
20; unix for example), the file will be called iodir+nom_fichier.
21;
22; @keyword COUNT {type=vector}
23; An optional vector containing the counts to be used in reading Value.
24;
25; COUNT is a 1-based vector with an element for
26; each dimension of the data to be written.
27;
28; The default matches
29; the size of the variable so that all data is written out.
30;
31; @keyword GROUP
32; The widget ID of the widget that calls XNCDF_LEC.
33;
34; When this ID is specified, a death of the caller results in a death
35; of XNCDF_LEC.
36;
37; @keyword OFFSET {type=vector}{default=[0, 0,...]}
38; An optional vector containing the starting position
39; for the read.
40;
41; @keyword SHIFT {type=vector}{default=[0, 0,...]}
42; A vector of integers, specifying for each dimension how much we have to shift it.
43;
44; See the function <proidl>SHIFT</proidl> for more explanations.
45;
46; BEWARE,
47; the shift is done on the biggest array before a possible reduction determined
48; by OFFSET and COUNT.
49;
50; On the other hand, it is done after the possible extraction
51; created by the STRIDE.
52;
53; @keyword STRIDE {type=vector}{default=[1, 1,...]}
54; An optional vector containing the strides, or sampling
55; intervals, between accessed values of the netCDF variable.
56;
57; @returns
58;  2 different cases:
59;  1) None attribute has been selected. In this case, res is the array we
60;     wanted to read.
61;  2) Some attributes has been selected. In this case, res is a structure
62;     whose the first element having the name of the variable is the values
63;     array and the other arguments are the select arguments.
64;
65; @uses
66; wididbase, infovariable, resultat, motcle
67;
68; @examples
69;
70;   IDL> help, xncdf_lec()
71;
72; @history
73; Sebastien Masson (smasson\@lodyc.jussieu.fr)
74;                      24/8/1999
75;
76; @version
77; $Id$
78;
79;-
80FUNCTION xncdf_lec, name, ATT=att, COUNT=count, GROUP=group, OFFSET=offset $
81                  , IODIR=iodir, SHIFT=shift, STRIDE=stride, VAR=var
82;
83  compile_opt idl2, strictarrsubs
84;
85   COMMON wididbase, base
86   COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient
87   COMMON resultat, res
88   COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar
89;------------------------------------------------------------
90; Trick for using keywords (we pass by variables declared in a common)
91;------------------------------------------------------------
92   res = -1
93   if keyword_set(att) then mcatt = att ELSE mcatt = 0
94   if keyword_set(count) then mccount =count  ELSE mccount = 0
95   if keyword_set(offset) then mcoffset = offset ELSE mcoffset = 0
96   if keyword_set(shift) then mcshift = shift ELSE mcshift = 0
97   if keyword_set(stride) then mcstride = stride ELSE mcstride = 0
98   if keyword_set(var) then mcvar = var ELSE mcvar = 0
99;------------------------------------------------------------
100; choice of the file's name
101;------------------------------------------------------------
102; What type of machine is used
103   thisOS = strupcase(strmid(!version.os_family, 0, 3))
104   CASE thisOS of
105      'MAC':sep = ':'
106      'WIN':sep = '\'
107      ELSE: sep = '/'
108   ENDCASE
109; If IODIR is not defined, we initialize it at the current directory
110   if NOT keyword_set(iodir) then cd,  current = iodir
111   mciodir = iodir
112; We complete IODIR with a separating character if needed.
113   IF rstrpos(iodir, sep) NE strlen(iodir)-1 THEN iodir = iodir+sep
114   if n_elements(name) EQ 0 then BEGIN ; If NAME is not defined, we find one thanks to the program dialog_pickfile.
115      name = dialog_pickfile(filter = iodir+'*.nc')
116      if name[0] EQ '' then return,  -1 ;If we do not have find anything, we go out.
117;We complete NAME by IODIR if NAME does not contain any directory separating character.
118   ENDIF ELSE if strpos(name, sep) EQ -1 then name = iodir+name
119   test = findfile(name)         ; Does the name looked for correspond to a file?
120   while test[0] EQ '' OR n_elements(test) GT 1 do BEGIN ; We look for one as long as it correspond to nothing!
121      test = test[0]
122      name = dialog_pickfile(filter = iodir+'*.nc')
123      if name EQ '' then return,  -1
124      test = findfile(name)
125   endwhile
126;------------------------------------------------------------
127; Opening of the file name.
128;------------------------------------------------------------
129   cdfid=ncdf_open(name)
130   contient=ncdf_inquire(cdfid)
131;------------------------------------------------------------
132; What does this file contain??
133;------------------------------------------------------------
134; Opening of the base window as columns
135   if n_elements(group) EQ 0 then base = widget_base(/column, title='Fichier: '+name, /align_left) $
136   ELSE base = widget_base(/column, title='Fichier: '+name, /align_left, GROUP_LEADER = group)
137; Opening of base sub-windows ;
138;------------------------------------------------------------
139; base 1 title having the file's name
140;------------------------------------------------------------
141   base1 = widget_base(base, /column, /align_center)
142   rien = widget_label(base1, value = 'NetCdf filename', /align_center)
143   rien = widget_text(base1, value = name, /align_center, uvalue=1, /editable) ;File's name we can change
144   rien = widget_label(base1, value = ' ') ; We jump a line
145;------------------------------------------------------------
146; base 2 General informations on the file
147;------------------------------------------------------------
148   base2 = widget_base(base, /column)
149;------------------------------------------------------------
150; Informations on global attributes
151;------------------------------------------------------------
152   if contient.ngatts NE -1 then begin
153      rien = widget_label(base2, value = 'Nombre de attributs globaux: '+ strtrim(contient.ngatts,1), /align_left)
154      for attiq=0,contient.ngatts-1 do BEGIN ; Loop on  the number of global attributes
155         name=ncdf_attname(cdfid,attiq,/global) ;Attribute's name
156         ncdf_attget,cdfid,name,value,/global ;Attribute's value
157         rien = widget_text(base2, value = name+': '+strtrim(string(value),1), xsize = 60, /scroll, /wrap, /align_right)
158      endfor
159      rien = widget_label(base2, value = ' ')
160   endif
161;------------------------------------------------------------
162;  Informations on dimensions
163;------------------------------------------------------------
164   rien = widget_label(base2, value = 'Nombre de dimensions: '+strtrim(contient.ndims,1), /align_left)
165   if contient.recdim NE -1 then begin ;  Loop on  the number of global attributes
166      ncdf_diminq,cdfid,contient.recdim,name,value ; Name and value of the dimension
167      rien = widget_label(base2, value = 'name de la dimension infinie: '+name, /align_left)
168   endif
169;
170   nomdim   =strarr(contient.ndims) ; Vector containing dimensions's name
171   tailledim=lonarr(contient.ndims) ; Vector containing dimensions's value
172   for dimiq=0,contient.ndims-1 do begin ; Loop on the number of dimensions
173      ncdf_diminq,cdfid,dimiq,name,value ; Name and value of the dimension
174      nomdim[dimiq]=name
175      tailledim[dimiq]=value
176      rien = widget_label(base2, value = name+' de taille: '+strtrim(value,1), /align_right)
177   ENDFOR
178   rien = widget_label(base2, value = ' ') ; We jump a line
179;------------------------------------------------------------
180; base 3 choice of the variable
181;------------------------------------------------------------
182   base3 = widget_base(base, /column)
183   rien = widget_label(base3, value = 'Nombre de variables: '+strtrim(contient.nvars,1), /align_left)
184   base31 = widget_base(base3, /row, /align_center)
185;Creation of a listename containing the name of all file's variables
186   listename = strarr(contient.nvars)
187   for varid=0,contient.nvars-1 do begin
188      varcontient=ncdf_varinq(cdfid,varid) ; that the variable contain
189      listename[varid] = varcontient.name
190   endfor
191   rien= widget_label(base31, value = 'variable')
192; Creation of a button with a pop-up menu.
193   base311=widget_droplist(base31,value=listename, uvalue=2)
194   rien = widget_label(base3, value = '')
195;------------------------------------------------------------
196; base 4 button done
197;------------------------------------------------------------
198   base4 = widget_base(base, /row)
199   base42=widget_button(base4,value='done', uvalue=3, /align_right)
200;Execution of the base window and of sub-windows
201   widget_control,base,/realize
202;------------------------------------------------------------
203   xmanager,'xncdf_lec',base
204;------------------------------------------------------------
205;------------------------------------------------------------
206;------------------------------------------------------------
207   return, res
208end
209;
210; La lecture de ce programme se fait de bas en haut:
211;   1) xncdf_lec
212;    -->2) xncdf_lec_event
213;       |--> 3) wid_var
214;            --> wid_var_event
215;
216;+
217;
218; @file_comments
219; Procedure called by xmanager when we press on a button of a second widget created by wid_var.
220;
221; @param EVENT {in}{required}
222; A structure characterizing the type of event which arrive to a widget number1 2
223;
224; @uses
225; wididbase,resultat,infovariable,indicewid,motcle
226;
227; @version
228; $Id$
229;
230;-
231PRO wid_var_event, event
232;
233  compile_opt idl2, strictarrsubs
234;
235   COMMON wididbase, base
236   COMMON resultat, res
237   COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient
238   COMMON indicewid_var, widbase1, widbase2111, widbase212, widbase213, selectatt
239   COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar
240;
241; What is the type of event?
242   widget_control, event.id, get_uvalue=uval
243   tailledimvar = tailledim[varcontient.dim]
244   if n_elements(uval) EQ 0 then return
245; case on the type of event.
246   case uval OF
247      1:BEGIN                   ; We change values in the array
248; We check that values put in the array are not totally false.
249         widget_control, widbase1, get_value = table
250; Is it the good type of argument?
251; If the type is wrong, we automatically change it by default values.
252         if event.x GT (size(table))[1] then return
253         if event.y GT (size(table))[2] then return
254         if size(table[event.x, event.y], /type) GE 6 $
255          OR size(table[event.x, event.y], /type) EQ 0 then BEGIN
256            if event.x EQ 1 then $
257             widget_control, widbase1, use_table_select = [1, event.y,1, event.y] $
258             , set_value = tailledimvar[event.y] $
259            ELSE widget_control, widbase1 $
260             , use_table_select = [event.x, event.y, event.x, event.y], set_value = 0
261         endif
262; Argument with a wrong name value?
263         table = fix(table)
264         case event.x of
265            0:BEGIN             ; We touched the offset
266               if table[0, event.y] LT 0 then BEGIN
267                  table[0, event.y] = 0
268                  widget_control, widbase1, use_table_select = [0, event.y, 0, event.y] $
269                   , set_value = 0
270              endif
271; If it exceed the dimension of the array, we put it at the max and the cont at 1.
272               if table[0, event.y] GT tailledimvar[event.y]/table[3, event.y] then begin
273                  widget_control, widbase1, use_table_select = [0, event.y,1, event.y] $
274                   , set_value = [tailledimvar[event.y]/table[3, event.y], 1]
275              ENDIF ELSE BEGIN
276; If, with the new offset, the cont is too big, we reduce it  until it goes well!
277                  if table[1, event.y] GT $
278                   (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] then begin
279                     widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $
280                      , set_value = (tailledimvar[event.y]/table[3, event.y])-table[0, event.y]
281                  endif
282               ENDELSE
283            END
284            1:BEGIN             ;We touched the cont.
285               if table[1, event.y] LT 1 then BEGIN
286                  table[1, event.y] = 1
287                  widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $
288                   , set_value = 1
289               endif
290; If it is too big, we reduce it  until it goes well!
291               if table[1, event.y] GT $
292                (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] then BEGIN
293                  widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $
294                   , set_value = (tailledimvar[event.y]/table[3, event.y])-table[0, event.y]
295               endif
296            END
297            2:BEGIN             ;We touched the shift.
298               widget_control, widbase1, use_table_select = [2, event.y, 2, event.y] $
299                , set_value = table[2, event.y] MOD (tailledimvar[event.y]/table[3, event.y])
300            END
301            3:BEGIN             ;We touched the stride.
302               if table[3, event.y] LT 1 then BEGIN
303                  table[3, event.y] = 1
304                  widget_control, widbase1, use_table_select = [3, event.y, 3, event.y] $
305                   , set_value = 1
306               endif
307               if table[3, event.y] EQ 0 then $ ;It must not be null.
308                widget_control, widbase1, use_table_select = [3, event.y, 3, event.y] $
309                , set_value = 1
310; It must not be too big.
311               if table[3, event.y] GT tailledimvar[event.y] then $
312                widget_control, widbase1, use_table_select = [0, event.y,3, event.y] $
313                , set_value = [0, 1, 0, tailledimvar[event.y]] $
314               ELSE BEGIN
315                  if table[1, event.y] GT $
316                   (tailledimvar[event.y]/table[3, event.y])-table[0, event.y] then begin
317                     widget_control, widbase1, use_table_select = [1, event.y, 1, event.y] $
318                      , set_value = (tailledimvar[event.y]/table[3, event.y])-table[0, event.y]
319                  endif
320               ENDELSE
321            END
322            ELSE:
323         endcase
324      END
325      2111:BEGIN                ;We touched buttons yes/no
326; We update the vector selectatt at 0 or 1 for the concerned attribute (number event.id).
327         selectatt[where(widbase2111 EQ event.id)] = event.select
328      end
329      31:BEGIN                  ;We pressed on 'get'
330         widget_control, widbase1, get_value = table
331         table = fix(table)
332         mcshift = where(table[2, *] NE 0)
333         mcoffset = table[0, *]
334         mccount = table[1, *]
335         mcstride = table[3, *]
336         if mcshift[0] NE -1 then BEGIN ; There are some shifts.
337; We read the wholeness of dimensions for which ones there is a shift.
338            mcoffset[mcshift] = 0
339            mccount[mcshift] = tailledimvar[mcshift]
340; We do not activate stride when there is no need because it makes write something weird on the screen.
341            if total(mcstride) EQ n_elements(mcstride) then $
342             ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount $
343            ELSE $
344             ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount, STRIDE = mcstride
345; To do the shift
346            mcshift = table[2, *]
347            mcoffset = table[0, *]
348            mccount = table[1, *]
349; We define the command allowing to do a shift.
350            commande = 'res=shift(res'
351            for dim = 0, varcontient.ndims-1 do commande = commande+','+string(table[2,dim])
352            commande = commande+')'
353            rien = execute(commande)
354; We redefine the command allowing to cut dimensions which has not been cut yet (ones we shift).
355            commande = 'res=res[' ; initialization of the command
356            for dim = 0, varcontient.ndims-1 do BEGIN
357               if mcshift[dim] EQ 0 then commande = commande+'*,' $
358               ELSE commande=commande+string(mcoffset[dim])+':'+string(mccount[dim]+mcoffset[dim]-1)+','
359            ENDFOR
360            commande = strmid(commande, 0, strlen(commande)-1)+']'
361            rien = execute(commande)
362; Case without shift, we read directly the good part of the array.
363         ENDIF ELSE BEGIN
364            if total(mcstride) EQ n_elements(mcstride) then $
365             ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount $
366            ELSE $
367             ncdf_varget, cdfid, varid, res, OFFSET = mcoffset, COUNT = mccount, STRIDE = mcstride
368         ENDELSE
369; Do we have to constitute a structure with selected attributes.
370         if total(selectatt) NE 0 then BEGIN ; There are selected attributes
371            res = create_struct(varcontient.name, res) ; We create the structure
372            selectatt = where(selectatt EQ 1) ; We find selected attributes
373            for attid = 0,  n_elements(selectatt)-1 do BEGIN ; for which we take
374               widget_control, widbase212[selectatt[attid]], get_value = attname ; the name
375               widget_control, widbase213[selectatt[attid]], get_value = attvalue ; the value
376              res = create_struct(res, attname[0], attvalue[0]) ; We concatenate the structure
377            endfor
378         endif
379         widget_control, event.top, /destroy ;We shut the second widget.
380         widget_control, base, /destroy ;We shut the first widget.
381         ncdf_close,cdfid
382      END
383      32:                       ;Case of the display of a held (with xdisplayfile)
384      33:widget_control, event.top, /destroy ;We shut the second widget.
385      ELSE:
386   endcase
387   return
388end
389;
390;+
391;
392; @file_comments
393; This procedure manage the second created widget when we call xncdf_lec.
394; This widget concern the reading of the variable.
395;
396; @param WIDID_PERE {type=scalar}{in}{required}
397; It contains the identity of the father widget which was
398; created by xncdf_lec and which has allowed to select the variable to be read.
399;
400; @returns
401; indirectement res (le tableau ou la structure resultat)
402;
403; @uses
404; resultat,infovariable,indicewid_var,motcle
405;
406; @version
407; $Id$
408;-
409PRO wid_var, widid_pere
410;
411  compile_opt idl2, strictarrsubs
412;
413   COMMON resultat, res
414   COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient
415   COMMON indicewid_var, widbase1, widbase2111, widbase212, widbase213, selectatt
416   COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar
417   res = -1
418;------------------------------------------------------------
419; Opening of the base window as columns.
420   widbase = widget_base(/column, title='variable: '+varcontient.name, /align_center, group_leader = widid_pere)
421;------------------------------------------------------------
422; Opening of the base subwindow
423;------------------------------------------------------------
424; widbase1 array of offsets
425;------------------------------------------------------------
426   rien = widget_label(widbase, value = ' ') ; We jump a line
427; Definition of labels of lines of the array
428   rowlab = string(tailledim[varcontient.dim])
429   for i = 0,  n_elements(rowlab)-1 do rowlab[i] = strtrim(rowlab[i], 1)
430   rowlab = nomdim[varcontient.dim]+replicate(': ', n_elements(varcontient.dim))+rowlab
431; Definition of array's initial values
432   valinit = lonarr(4, n_elements(varcontient.dim))
433; column 0 : offsets
434   if keyword_set(mcoffset) AND n_elements(mcoffset) EQ varcontient.ndims THEN $
435    valinit[0,*]=mcoffset ELSE valinit[0, *] = 0
436; colomn 1 : counts
437   if keyword_set(mccount) AND n_elements(mccount) EQ varcontient.ndims THEN  $
438    valinit[1,*]=mccount ELSE valinit[1, *] = tailledim[varcontient.dim]
439; column 2 : shifts
440   if keyword_set(mcshift) AND n_elements(mcshift) EQ varcontient.ndims THEN $
441    valinit[2,*]=mcshift ELSE valinit[2, *] = 0
442; column 3 : strides
443   if keyword_set(mcstride) AND n_elements(mcstride) EQ varcontient.ndims THEN $
444    valinit[3,*]=mcstride ELSE valinit[3, *] = 1
445; test of initial values of the array
446   valinit = fix(valinit)
447   valinit[3, *] = 1 > valinit[3, *] < tailledim[varcontient.dim] ; test of strides
448   valinit[0, *] = 0 > valinit[0, *] < tailledim[varcontient.dim] ; test of offsets
449; test of counts
450   valinit[1, *] = 1 > valinit[1, *] < ((tailledim[varcontient.dim]/valinit[3, *])-valinit[0, *])
451   valinit[2, *] = valinit[2, *] MOD (tailledim[varcontient.dim]/valinit[3, *]) ; test of shifts
452; declaration of the array
453   widbase1 = widget_table(widbase, row_labels = rowlab, value = valinit, /editable $
454                           , column_labels = ['Offset', 'Count', 'Shift', 'Stride'], uvalue = 1)
455; un petit blabla
456   rien = widget_label(widbase, value = 'ATTENTION: Faire des ''return'' pour que les valeurs', /align_center)
457   rien = widget_label(widbase, value = 'du tableau ou des textes soient bien prises en compte', /align_center)
458;------------------------------------------------------------
459; widbase2 choice of attributes
460;------------------------------------------------------------
461   rien = widget_label(widbase, value = ' ') ; We jump a line
462   widbase2 = widget_base(widbase, /column)
463; To each attribute, we created a widget (widbase21) containing in line a button
464; yes/no (widbase211), and two widget text (widbase212, widbase213) comprising the
465; name and the value of the attribute.
466   widbase21 = lonarr(varcontient.natts)
467   widbase211 = lonarr(varcontient.natts)
468   widbase2111 = lonarr(varcontient.natts)
469; Vector which will serve to know which yes/no are selected. see. wid_var_event
470   selectatt = lonarr(varcontient.natts)
471   selectatt[*] = 0
472   widbase212 = lonarr(varcontient.natts)
473   widbase213 = lonarr(varcontient.natts)
474   for attid = 0, varcontient.natts-1 do BEGIN ;Loop on the number of attribute.
475      widbase21[attid] = widget_base(widbase2, /row)
476      name=ncdf_attname(cdfid,varid,attid)
477      ncdf_attget,cdfid,varid,name,value
478      widbase211[attid] = widget_base(widbase21[attid], /nonexclusive)
479      widbase2111[attid]  = widget_button(widbase211[attid], value = ' ', uvalue = 2111)
480      widbase212[attid] = widget_text(widbase21[attid], value = name, /editable)
481      widbase213[attid] = widget_text(widbase21[attid], value=strtrim(string(value),1), /editable)
482   endfor
483;------------------------------------------------------------
484; widbase3 buttons of the bottom.
485;------------------------------------------------------------
486   widbase3 = widget_base(widbase, /row,/align_center)
487   widbase31=widget_button(widbase3,value='GET', uvalue=31)
488   widbase32=widget_button(widbase3,value='Help', uvalue=32)
489   widbase33=widget_button(widbase3,value='DONE', uvalue=33)
490;------------------------------------------------------------
491;execution of the base window and of sub-window.
492;------------------------------------------------------------
493   widget_control,widbase,/realize
494;------------------------------------------------------------
495   xmanager,'wid_var',widbase
496   return
497end
498;
499;+
500;
501; @file_comments
502; Procedure called by xmanager when we press a button of the first widget
503; created by xncdf_lec
504;
505; @param EVENT
506; A structure characterising the event type which arrive at the widget number 1.
507;
508; @uses
509; resultat, infovariable, motcle
510;
511; @version
512; $Id$
513;
514;-
515PRO xncdf_lec_event, event
516;
517  compile_opt idl2, strictarrsubs
518;
519   COMMON resultat, res
520   COMMON infovariable, cdfid, listename, contient, nomdim, tailledim, varid, varcontient
521   COMMON motcle, mcatt, mccount, mcoffset, mciodir, mcshift, mcstride, mcvar
522; What is the type of event?
523   widget_control, event.id, get_uvalue=uval
524; case on the type of event.
525   case uval of
526      1:BEGIN                   ; We want to read an other file
527         widget_control, event.id, get_value = nom ; We recuperate the name.
528         widget_control, event.top, /destroy ;We shut the widget.
529         ncdf_close,cdfid       ;We shut the wrong file which has been opened.
530;We call back xncdf_lec
531         res = xncdf_lec(nom[0], ATT = mcatt, COUNT = mccount, OFFSET = mcoffset, IODIR = mciodir $
532                         , SHIFT = mcshift,  STRIDE = mcstride, VAR = mcvar)
533         return
534      END
535      2:BEGIN                   ; A variable is selected.
536         varid = event.index    ; We recuperat its number in the file Netcdf
537         varcontient = ncdf_varinq(cdfid,varid)
538         wid_var, event.top     ; We call the program which launch the second widget. See sooner.
539      END
540      3:BEGIN                   ; button done
541         widget_control, event.top, /destroy ; We delete the widget
542         ncdf_close,cdfid       ; We shut the file.
543      END
544      ELSE:
545   endcase
546   return
547end
Note: See TracBrowser for help on using the repository browser.