source: trunk/SRC/ToBeReviewed/PLOTS/DESSINE/tvplus.pro @ 114

Last change on this file since 114 was 114, checked in by smasson, 18 years ago

new compilation options (compile_opt idl2, strictarrsubs) in each routine

  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 12.5 KB
Line 
1;------------------------------------------------------------
2;------------------------------------------------------------
3;------------------------------------------------------------
4;+
5; NAME: tvplus
6;
7; PURPOSE: enhanced version of tvscl
8;
9; CATEGORY: quick exploration of 2D arrays
10;
11; CALLING SEQUENCE: tvplus,z2d [,cellsize]
12;
13; INPUTS:
14;
15;    z2d: 2D array to visualize
16;
17;    cellsize: (optional) this is the size (in pixel) of the square
18;    representing 1 array element. By default, this size is computed
19;    automatically in order that the size of the plotting window do
20;    not exceed the screen size. If the user specify a large value
21;    of cellsize that forces tvplus to create a window larger than
22;    the screen, a "scrolling window" will be displayed instead of a
23;    regular window. Unfortunately the nice fonctionnalities of tvplus
24;    are not coded for "scrolling window" case...
25;
26; KEYWORD PARAMETERS:
27;
28;       BOTTOM: The lowest color index of the colors to be loaded in
29;       the bar. default is 0.
30;
31;       C_NAN: The color number that should be used for the NaN values.
32;       default value is !d.n_colors < 255
33;
34;       C_MASK: The color number that should be used for the mask values.
35;       default value is 0
36;
37;       OFFSET: 2 elements vector used by tvplus itself when shoing zoom.
38;       It is used to shift the ranges of xaxis and yaxis.
39;       For example: tvplus,sst[x1:x2,y1:y2],offest=[x1,y1]
40;
41;       MASK: The mask value. Note that if abs(mask) < 1.e6, then the
42;       exact value of the mask is used to find the maskwd point.
43;       if abs(mask) > 1.e6, the test to find the masked value is ge
44;       abs(mask)/10. This is necessary to avoid the rounding errors
45;
46;       MIN and MAX: scalars used to specify the min and max values
47;       of the color bar. default is from 0 to !d.n_colors < 255
48;
49;       NCOLORS:  This is the number of colors in the color
50;       bar. default is !d.n_colors<255 -1
51;
52;       NOINTERP: used this keyword if you don't whant that the values
53;       are interpolated between 0 (or min) and !d.n_colors < 255 (or max).
54;       This can be for example usefull when working on byte type arrays.
55;
56;       NOUSEINFOS: activite to supress the printed message explaining
57;       how to use tvplus
58;
59;       WINDOW: Number of the window used to display the array values.
60;       default is window number 0.
61;
62; OUTPUTS: no (except the printed finformations, see below)
63;
64; COMMON BLOCKS: no
65;
66; SIDE EFFECTS:
67;
68; use your mouse to scan the array values...
69;     left button  : mouse position and associated array value
70;     middle button: use it twice to define a zoom box
71;     right button : quit
72;
73; RESTRICTIONS: the nice fonctionnalities of tvplus are not coded
74;               for "scrolling window" case...
75;
76; EXAMPLE:  IDL> tvplus, dist(100)
77;
78; MODIFICATION HISTORY: Sebastien Masson (smasson@lodyc.jussieu.fr)
79;                       18/12/98
80; Aug 2005: quick cleaning + english
81;-
82;------------------------------------------------------------
83;------------------------------------------------------------
84;------------------------------------------------------------
85PRO tvplus, z2d, cellsize, BOTTOM = bottom, C_MASK = c_mask, C_NAN = c_nan, WINDOW = window $
86            , MIN = min, MAX = max, MASK = mask, OFFSET = offset, NOUSEINFOS = NOUSEINFOS $
87            , NCOLORS = ncolors, NOINTERP = nointerp, _EXTRA = ex
88;
89;
90  compile_opt idl2, strictarrsubs
91;
92  IF n_elements(z2d) EQ 0 THEN return
93  arr = reform(float(z2d))
94;------------------------------------------------------------
95; check the size of the input array
96;------------------------------------------------------------
97  if (size(arr))[0] NE 2 then begin
98    ras = report('Input array must have only 2 dimensions and not '+ strtrim(size(arr, /n_dimensions), 1))
99    return
100  endif
101;------------------------------------------------------------
102; def of ncolmax, bottom, topcol et ncolors
103;------------------------------------------------------------
104  ncolmax = !d.n_colors < 256
105  IF N_ELEMENTS(bottom) EQ 0 THEN bottom = 0
106  if NOT keyword_set(ncolors) then ncolors = ncolmax-bottom
107  topcol = (bottom+ncolors-1) < (ncolmax-1)
108;------------------------------------------------------------
109; get default values of !x, !y, !z
110;------------------------------------------------------------
111;   xenvsauve = !x & yenvsauve = !y & penvsauve = !p
112  reinitplt, /z, /invert
113;------------------------------------------------------------
114; Do we have NaN values in arr???
115;------------------------------------------------------------
116  nan = total(finite(z2d, /nan)) < 1
117  if keyword_set(nan) then begin
118    nanindex = where(finite(z2d, /nan) EQ 1)
119    arr[nanindex] = min(arr, /nan)
120  endif
121;------------------------------------------------------------
122; Compute the size (in pixel) of the square representing 1
123; point of the input array
124;------------------------------------------------------------
125  dimensions = GET_SCREEN_SIZE()
126  if n_elements(cellsize) EQ 0 then BEGIN
127    cellsize = min(floor(dimensions/(size(z2d))[1: 2]*.75))
128  ENDIF ELSE $
129; we need to use a scrolling bar window
130  if cellsize GE min(floor(dimensions/(size(z2d))[1: 2]*.75)) then scrolling = 1
131  if cellsize LT 1 then begin
132    cellsize = 1
133    scrolling = 1
134  endif
135;------------------------------------------------------------
136; Change the value of the masked value for the min of the non-masked values
137;------------------------------------------------------------
138  if n_elements(mask) then BEGIN
139    if abs(mask) LT 1e6 then BEGIN
140      masked = where(arr EQ mask)
141      if masked[0] NE -1 then arr[masked] = min(arr[where(arr NE mask)])
142    ENDIF ELSE BEGIN
143      masked = where(abs(arr) GE abs(mask)/10.)
144      if masked[0] NE -1 then arr[masked] = min(arr[where(abs(arr) LT abs(mask)/10.)])
145    ENDELSE
146  ENDIF ELSE masked = -1
147;------------------------------------------------------------
148; apply min/max keywords
149;------------------------------------------------------------
150  if n_elements(min) NE 0 then BEGIN
151    arr = min > arr
152    truemin = min
153  ENDIF ELSE truemin = min(arr)
154  if n_elements(max) NE 0 then BEGIN
155    arr = arr < max
156    truemax = max
157  ENDIF ELSE truemax = max(arr)
158;
159  IF truemin EQ truemax THEN BEGIN
160    dummy = report('constant value everywhere: '+ strtrim(truemin, 1))
161    return
162  ENDIF
163;------------------------------------------------------------
164; apply other keywords (nointerp, c_nan, c_mask)
165;------------------------------------------------------------
166  if NOT keyword_set(nointerp) then BEGIN
167; interpolation between bottom and bottom+ncolors-1
168    m = 1.*(ncolors-1)/(truemax-truemin)
169    p = bottom-1.*truemin*m
170    arr = round(1.*m*arr+p)
171  endif
172; set c_nan for NaN values
173  if keyword_set(nan) then begin
174    if n_elements(c_nan) NE 0 THEN arr[nanindex] = c_nan <  (ncolmax -1) $
175    ELSE arr[nanindex] = topcol
176  endif
177; c_mask for masked values
178  if n_elements(c_mask) NE 0 AND masked[0] NE -1 THEN $
179    arr[masked] = c_mask < (ncolmax -1)
180; use byte type to save memory
181  arr = byte(arr)
182; increase the size of the array in order to be displayed
183; with the suitable size
184  arr = congridseb(arr, (size(arr))[1]*cellsize, (size(arr))[2]*cellsize)
185;------------------------------------------------------------
186; open a window with the correct size
187;------------------------------------------------------------
188  nx = (size(arr))[1]
189  ny = (size(arr))[2]
190; margin size (in pixel)
191  xyaspect = 1.*nx/ny
192  if xyaspect GE 1 THEN marginpix = 1.*[25, 25, 75, 25] ELSE marginpix = 1.*[25, 100, 25, 25]
193;
194  if n_elements(scrolling) EQ 0 then BEGIN ; open the regular window
195    if NOT keyword_set(window) then window = 0
196    window, window, xsize = nx+marginpix[0]+marginpix[1] $
197            , ysize = ny+marginpix[2]+marginpix[3]
198; for 24 bits colors, make sure thate the background color is the good one...
199    if !d.n_colors gt 256 then BEGIN
200      device, decomposed = 1
201      !p.background = 'ffffff'x
202      plot, [0], [0], xstyle = 5, ystyle = 5
203      device, decomposed = 0
204    endif
205    tv, arr, marginpix[0], marginpix[2], _EXTRA = ex
206;
207; axis and plot frame
208;
209; get the normalized position of the tv (we just done above)
210; to know where the frame should be drawn
211    poscadre = fltarr(4)
212    poscadre[0] = marginpix[0]/!d.x_size
213    poscadre[2] = 1.-marginpix[1]/!d.x_size
214    poscadre[1] = marginpix[2]/!d.y_size
215    poscadre[3] = 1-marginpix[3]/!d.y_size
216; Use plot to draw the frame
217    if NOT keyword_set(offset) then offset = [0, 0]
218    !p.position = poscadre
219    plot, [0], [0], /nodata, /noerase, position = poscadre, color = 0 $
220          , xstyle = 1, ystyle = 1, xticklen = 1, yticklen = 1 $
221          , xrange = 1.*[0, nx]/cellsize-.5+offset[0] $
222          , yrange = 1.*[0, ny]/cellsize-.5+offset[1], _extra = ex
223    xenvsauve = !x & yenvsauve = !y & penvsauve = !p
224;
225; draw the colorbar
226;
227    IF truemin ne truemax THEN BEGIN
228      if xyaspect ge 1 then $
229        posbar = [25./!d.x_size, 25./!d.y_size, 1-25./!d.x_size, 50./!d.y_size] $
230        ELSE posbar = [1-75./!d.x_size, 25./!d.y_size, 1-50./!d.x_size, 1-25./!d.y_size]
231    if keyword_set(nointerp) then BEGIN & truemin = 0 & truemax = ncolmax & endif
232      colorbar, min = truemin, max = truemax, division = 10, cb_color = 0, position = posbar $
233                , vertical = xyaspect lt 1, /right, BOTTOM = bottom, NCOLORS = ncolors, _EXTRA = ex
234    ENDIF
235;      !p.position = poscadre
236  ENDIF ELSE BEGIN
237;------------------------------------------------------------
238; scrolling bar window case...
239;------------------------------------------------------------
240; for 24 bits colors, make sure thate the background color is the good one...
241    if !d.n_colors gt 256 then begin
242      window, /pixmap
243      device, decomposed = 1
244      !p.background = 'ffffff'x
245      plot, [0], [0]
246      device, decomposed = 0
247    endif
248    slide_image, arr $          ; on le dessine ds une fenetre avec une scrolling bar
249                 , xsize = nx, ysize = ny $
250                 , xvisible = round(.7*dimensions[0]) < (size(arr))[1] $
251                 , yvisible = round(.7*dimensions[1]) < (size(arr))[2], /register, congrid = 0, show_full = 0
252    return
253  ENDELSE
254;------------------------------------------------------------
255; Use the mouse to get nice functionalities
256;------------------------------------------------------------
257; format to print the mouse position
258  CASE 1 OF
259    nx LT 10:fmt1 = '(i1)'
260    nx LT 100:fmt1 = '(i2)'
261    nx LT 1000:fmt1 = '(i3)'
262    nx LT 10000:fmt1 = '(i4)'
263    ELSE:fmt1 = ''
264  ENDCASE
265  CASE 1 OF
266    ny LT 10:fmt2 = '(i1)'
267    ny LT 100:fmt2 = '(i2)'
268    ny LT 1000:fmt2 = '(i3)'
269    ny LT 10000:fmt2 = '(i4)'
270    ELSE:fmt2 = ''
271  ENDCASE
272;
273  if NOT keyword_set(nouseinfos) then begin
274    print, 'left button  : mouse position and associated array value'
275    print, 'middle button: use it twice to define a zoom box'
276    print, 'right button : quit'
277  endif
278  cursor, x, y, /device, /down
279  x = x-marginpix[0] & x = 0 > floor(x/cellsize) < ((size(arr))[1]/cellsize-1)
280  y = y-marginpix[2] & y = 0 > floor(y/cellsize) < ((size(arr))[2]/cellsize-1)
281  while (!mouse.button ne 4) do BEGIN
282    case !mouse.button of
283      0:return
284      1:BEGIN                   ; get value
285        if x LE nx/cellsize AND y LE ny/cellsize then begin
286          print, '(x, y) = (' + string(x+offset[0], format = fmt1) $
287                 + ', ' + string(y+offset[1], format = fmt2) $
288                 + '), value = '+strtrim(float((reform(z2d))[x, y]), 1)
289        ENDIF
290        cursor, x, y, /device, /down
291        x = x-marginpix[0] & x = 0 > floor(x/cellsize) < ((size(arr))[1]/cellsize-1)
292        y = y-marginpix[2] & y = 0 > floor(y/cellsize) < ((size(arr))[2]/cellsize-1)
293      END
294      2:BEGIN                   ; zoom
295        cursor, x2, y2, /device, /down
296        x2 = x2-marginpix[0] & x2 =  0 > floor(x2/cellsize) < ((size(arr))[1]/cellsize-1)
297        y2 = y2-marginpix[2] & y2 =  0 > floor(y2/cellsize) < ((size(arr))[2]/cellsize-1)
298        x =  [x, x2] & x =  x[sort(x)]
299        y =  [y, y2] & y =  y[sort(y)]
300        IF keyword_set(OFFSET) THEN offset = [x[0], y[0]]+offset ELSE offset = [x[0], y[0]]
301        tvplus, z2d[x[0]:x[1], y[0]:y[1] ], WINDOW = window, MIN = min, MAX = max $
302                , MASK = mask, C_MASK = c_mask, C_NAN = c_nan, /NOUSEINFOS, OFFSET = OFFSET $
303                , NCOLORS = ncolors, NOINTERP = nointerp, BOTTOM = bottom, _EXTRA = ex
304        return
305      END
306      ELSE:
307    endcase
308  ENDWHILE
309;------------------------------------------------------------
310  !x = xenvsauve & !y = yenvsauve & !p = penvsauve
311  !x.range = 1.*[0, nx]/cellsize-.5+offset[0]
312  !y.range = 1.*[0, ny]/cellsize-.5+offset[1]
313;------------------------------------------------------------
314  return
315end
Note: See TracBrowser for help on using the repository browser.