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

Last change on this file since 163 was 163, checked in by navarro, 18 years ago

header improvements : type of parameters and keywords, default values, spell checking + idldoc assistant (IDL online_help)

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