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

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

improvements of headers (alignments of IDL prompt in examples)

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