;---------------------------------------------------------------- ; $Id: wv_plot3d_wps.pro,v 1.21 2001/08/14 22:48:16 chris Exp $ ; ; Copyright (c) 1999-2001, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ;+ ; NAME: ; WV_PLOT3D_WPS ; ; PURPOSE: ; ; This function runs the IDL Wavelet Toolkit wavelet power ; spectrum widget. ; ; CALLING SEQUENCE: ; ; Result = WV_PLOT3D_WPS( Array [, X] [, Y] ; [, XTITLE=xtitle] [, YTITLE=ytitle] ; [, XUNITS=xunits] [, YUNITS=yunits] ; [, UNITS=units] [, TITLE=title] ) ; ; INPUTS: ; ; Array: A one- or two-dimensional array of data to be analyzed. ; ; X: An optional vector of uniformly-spaced values giving the ; location of points along the first dimension of Array. ; The default is 0, 1, 2,..., Nx-1, where Nx is the size ; of the first dimension. ; ; Y: An optional vector of uniformly-spaced values giving the ; location of points along the second dimension of Array. ; The default is 0, 1, 2,..., Ny-1, where Ny is the size ; of the second dimension. ; ; KEYWORDS: ; ; GROUP_LEADER: The widget ID of an existing widget that serves ; as "group leader" for the newly-created widget. When a group ; leader is killed, for any reason, all widgets in the group are ; also destroyed. ; ; TITLE: A scalar string giving the label to be used for the widget. ; The default is "WPS:". ; ; UNITS: A scalar string giving the units of Array. ; ; XTITLE: A scalar string giving the label to be used for the ; first dimension. ; ; XUNITS: A scalar string giving the units of X. ; ; YTITLE: A scalar string giving the label to be used for the ; y-axis (for a 1D vector) or for the second dimension (for a 2D array). ; ; YUNITS: A scalar string giving the units of Array (for a 1D vector) ; or the units of Y (for a 2D array). ; ; OUTPUTS: ; ; Result: The widget ID of the newly-created widget. ; ; REFERENCE: ; IDL Wavelet Toolkit Online Manual ; ; MODIFICATION HISTORY: ; Written by CT, 1999 ; May 2000, CT: Removed RESOLVE_ALL ; August 2000, CT: Add "Open State", "Save State". ; Add hide/show Wavelet & View panels. ; Add "zero phase lines" button. ;- ; Variable name conventions used herein: ; r==Reference to Object ; p==pointer ; w==widget ID ; ;+ ; NAME: ; CW_FONT_SELECT ; ; PURPOSE: ; ; CALLING SEQUENCE: ; ; INPUTS: ; Parent: The ID of the parent widget. ; ; KEYWORD PARAMETERS: ; FRAME: Set this keyword to have a frame drawn around the ; widget. The default is FRAME=0. ; UVALUE: The user value for the widget. ; UNAME: The user name for the widget. ; VALUE: The initial value of the slider ; ; OUTPUTS: ; The ID of the created widget is returned. ; ; PROCEDURE: ; WIDGET_CONTROL, id, SET_VALUE=value can be used to change the ; current value displayed by the widget. ; ; WIDGET_CONTROL, id, GET_VALUE=var can be used to obtain the current ; value displayed by the widget. ; ; MODIFICATION HISTORY: ;- ;----------------------------------------------------------------------------- PRO cw_font_select_set_value, id, set_value COMPILE_OPT hidden, idl2 ; Set the value of both the slider and the label ON_ERROR, 2 ;return to caller stash = WIDGET_INFO(id, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY IF (N_TAGS(set_value) NE 2) THEN MESSAGE, $ 'Incorrect structure for Value.' fontIndex = (WHERE(state.sFontList EQ set_value.name))[0] IF (fontIndex EQ -1) THEN BEGIN ; now try fontcode fontIndex = (WHERE(state.sFontCode EQ set_value.name))[0] IF (fontIndex EQ -1) THEN MESSAGE, /INFO, $ 'Unknown font name: '+set_value.name ENDIF IF (fontIndex GE 0) THEN WIDGET_CONTROL, state.wFontList, $ SET_DROPLIST_SELECT=fontIndex sizeIndex = MAX(WHERE(state.sFontSize LE set_value.size)) > 0 WIDGET_CONTROL, state.wFontSize, $ SET_DROPLIST_SELECT=sizeIndex WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY RETURN END ;----------------------------------------------------------------------------- FUNCTION cw_font_select_get_value, id COMPILE_OPT hidden, idl2 ; Return the value ON_ERROR, 2 ;return to caller stash = WIDGET_INFO(id, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY ; See which widget was adjusted fontIndex = WIDGET_INFO(state.wFontList, /DROPLIST_SELECT) fname = state.sFontList[fontIndex] sizeIndex = WIDGET_INFO(state.wFontSize, /DROPLIST_SELECT) fsize = state.sFontSize[sizeIndex] WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY RETURN, { NAME:fname, SIZE:fsize } END ;----------------------------------------------------------------------------- FUNCTION cw_font_select_event, event COMPILE_OPT hidden, idl2 ; Retrieve the structure from the child that contains the sub ids parent = event.handler stash = WIDGET_INFO(parent, /CHILD) WIDGET_CONTROL, stash, GET_UVALUE=state, /NO_COPY ; See which widget was adjusted fontIndex = WIDGET_INFO(state.wFontList, /DROPLIST_SELECT) fname = state.sFontCode[fontIndex] sizeIndex = WIDGET_INFO(state.wFontSize, /DROPLIST_SELECT) fsize = state.sFontSize[sizeIndex] WIDGET_CONTROL, stash, SET_UVALUE=state, /NO_COPY RETURN, { ID:parent, TOP:event.top, HANDLER:0L, $ NAME:fname, SIZE:fsize} END ;----------------------------------------------------------------------------- FUNCTION cw_font_select, parent, $ FRAME=frame, $ VALUE = set_value, $ UNAME=uname, $ _EXTRA=_extra COMPILE_OPT hidden, idl2 ON_ERROR, 2 ;return to caller IF (N_PARAMS() EQ 0) THEN MESSAGE, 'Incorrect number of arguments' ; Defaults for keywords IF NOT KEYWORD_SET(uname) THEN $ uname='CW_FONT_SELECT_UNAME' IF (N_ELEMENTS(set_value) EQ 0) THEN $ set_value = "" wBase = WIDGET_BASE(parent, $ EVENT_FUNC = 'CW_FONT_SELECT_EVENT', $ FRAME = frame, $ FUNC_GET_VALUE='CW_FONT_SELECT_GET_VALUE', $ PRO_SET_VALUE='CW_FONT_SELECT_SET_VALUE', $ /ROW, $ UNAME=uname, $ _EXTRA=_extra) rClip = OBJ_NEW('IDLgrClipboard', $ DIMENSIONS=[1,1]) fontlist = rClip->GetFontNames('*',/IDL,STYLE='*') OBJ_DESTROY, rClip fontcode = fontlist hershey = [ $ ['','3'], $ ['Bold','5'], $ ['Serif','6'], $ ['Italic','8'], $ ['Heavy','17'], $ ['Bold Italic','18']] hersheyNames = REFORM('Hershey ' + hershey[0,*]) hersheyCodes = REFORM('Hershey*' + hershey[1,*]) fontlist = [fontlist, hersheyNames] fontcode = [fontcode, hersheyCodes] index = SORT(fontlist) fontlist = fontlist[index] fontcode = fontcode[index] wFontList = WIDGET_DROPLIST(wBase, $ VALUE=fontlist) fontsize = [6,7,8,9,10,11,12, $ 14,16,18,20,22,24,26,28, $ 36,48,72] wFontSize = WIDGET_DROPLIST(wBase, $ VALUE=STRTRIM(fontsize,2)) state = {wBase:wBase, $ wFontList:wFontList, $ sFontList:fontlist, $ sFontCode:fontcode, $ wFontSize:wFontSize, $ sFontSize:fontsize} WIDGET_CONTROL, WIDGET_INFO(wBase, /CHILD), SET_UVALUE=state IF (N_TAGS(set_value) EQ 2) THEN $ CW_FONT_SELECT_SET_VALUE, wBase, set_value RETURN, wBase END ;-------------------------------------------------------------------- FUNCTION wv_plot3d_cwt, family, order, data, xData, $ X=x, Y=y COMPILE_OPT strictarr, hidden nDim = SIZE(data,/N_DIMENSION) IF (nDim NE 1) THEN MESSAGE, $ 'CWT not implemented for two-dimensional arrays.' cwt = WV_CWT(data,family,order,SCALE=scale,/PAD) y = ALOG(scale)/ALOG(2d) x = xData RETURN, cwt END ;-------------------------------------------------------------------- FUNCTION wv_plot3d_dwt, family, order, data, xData, $ X=x, Y=y COMPILE_OPT strictarr, hidden nDim = SIZE(data,/N_DIMENSION) dim = SIZE(data,/DIMENSIONS) ; find next larger power of 2 to embed within dim = 2L^(LONG(ALOG(dim)/ALOG(2)+0.99999)) nx = dim[0] IF (nDim EQ 1) THEN BEGIN data_in = DBLARR(nx) ENDIF ELSE BEGIN ny = dim[1] data_in = DBLARR(nx,ny) ENDELSE ; embed input data within larger array data_in[0,0] = data wave_function = STRCOMPRESS('wv_fn_'+family,/REMOVE_ALL) wInfo = CALL_FUNCTION(wave_function, order, $ scaling,wavelet,ioff,joff) dwt = WV_DWT(data_in,scaling,wavelet,ioff,joff,/DOUBLE) IF (nDim EQ 1) THEN BEGIN ; time series dwt[0:1] = SQRT(TOTAL(dwt[0:1]^2)/2.) ; first 2 coeffs are "mean" power2 = FIX(ALOG(nx)/ALOG(2)) ny = power2 y = LINDGEN(ny) + 1 nx = N_ELEMENTS(data)/2 x = xData[2L*LINDGEN(nx)] ;* starred lines are for extending the axes for Logo plots ;* ny = power2 + 1 ;* y = LINDGEN(ny) + 1 ;* nx = 2L^(power2-1) + 1 ;* x = (*(*pState).pXdata)[2L*LINDGEN(nx-1)] ;* x = [x,MAX(x) + (x[1]-x[0])] dwt_big = FLTARR(nx,ny) FOR j=0,power2-1 DO BEGIN index = 2L^j + LINDGEN(nx)/(2L^(power2-j-1)) dwt_big[0,power2-j-1] = dwt[index] ;* index = 2L^j + LINDGEN(nx-1)/(2L^(power2-j-1)) ;* dwt_big[0,power2-j] = dwt[index] ENDFOR dwt = TEMPORARY(dwt_big) ; n = N_ELEMENTS(dwt) ; y = power2 - FIX(ALOG(LINDGEN(n))/ALOG(2)) ; x = (LINDGEN(n) - 2L^(power2-y))*(2L^y) > 0 ENDIF ELSE BEGIN ; 2D array x = LINDGEN(nx) y = LINDGEN(ny) ENDELSE RETURN, dwt END ;-------------------------------------------------------------------- FUNCTION wv_rescale_axis, values, $ EXPONENT=exponent, $ SCALE_FACTOR=scale_factor, $ SCALE_STRING=scale_string, $ TITLE=title COMPILE_OPT strictarr, hidden n = N_ELEMENTS(values) minn = MIN(values[WHERE(values NE 0.)]) exponent = (N_ELEMENTS(exponent) EQ 0) ? $ FIX(ALOG10(ABS(minn))) : exponent scale_factor = 10d^exponent scale_string = '!3!E !Nx!E !N!X10!U' + STRTRIM(exponent,2) + '!N' IF (ABS(exponent) LT 4) THEN BEGIN dummy = TEMPORARY(exponent) scale_factor = 1 scale_string = '' RETURN, values ; no need to rescale ENDIF result = values/scale_factor IF (N_ELEMENTS(title) EQ 1) THEN BEGIN units = STRPOS(title,'(') CASE (units) OF -1: title = title + ' (' + scale_string + ')' ELSE: title = STRMID(title,0,units+1) + $ scale_string + ' ' + STRMID(title,units+1,255) ENDCASE ENDIF scale_string = '(' + scale_string + ')' RETURN,result END ;-------------------------------------------------------------------- PRO wv_plot3d_redraw, pState, $ THREED=threeD, $ ZCUTOFF=zcutoff, $ COLORBARTITLE=colorbartitle COMPILE_OPT strictarr, hidden rView = (*pState).rView pX = (*pState).pX pY = (*pState).pY pZ = (*pState).pZ pGws = (*pState).pGws pPhase = (*pState).pPhase rView->GetProperty,UVALUE=sWps oneD = OBJ_VALID(sWps.rTimeSeries) ; find Z range zmin = MIN(*pZ,MAX=zmax) zmin = 0.0 < zmin IF (N_ELEMENTS(zcutoff) EQ 1) THEN BEGIN zmin = (zmin > zcutoff) < zmax ENDIF IF (zmax EQ zmin) THEN zmin = zmax - 0.1D zcutoff = zmin zscale = 0.65 zs = zscale*[-FLOAT(zmin)/(zmax - zmin),1.0/(zmax - zmin)] ; add data to surface plot zvalues = zmin > *pZ < zmax offset = 0 IF (threeD EQ 0) THEN offset = zmin sWps.rSurface->SetProperty, $ DATAX=*pX,DATAY=*pY,DATAZ=zvalues*threeD+offset, $ SKIRT=zmin, $ VERT_COLORS=(BYTSCL(zvalues,TOP=253)+1b)[*] sWps.rSurface->GetProperty, $ STYLE=style, $ XRANGE=xrange, $ YRANGE=yrange ; find coord conversions xmin = MIN(xrange,MAX=xmax) ymin = MIN(yrange,MAX=ymax) xs = [-0.45 - FLOAT(xmin)/(xmax - xmin),1./(xmax - xmin)] ys = [-0.45 - FLOAT(ymin)/(ymax - ymin),1./(ymax - ymin)] ys2 = ys ; IF oneD THEN ys2 = [0.55 + FLOAT(ymin)/(ymax - ymin),-1./(ymax - ymin)] sWps.rPhaseImage->SetProperty, $ XCOORD_CONV=xs,YCOORD_CONV=ys2,ZCOORD_CONV=zs ; change coord conversions for surface plot sWps.rSurface->SetProperty, $ UVALUE=style, $ XCOORD_CONV=xs,YCOORD_CONV=ys2,ZCOORD_CONV=zs ; change X axis ranges & ticks sWps.rXaxis->SetProperty, $ HIDE=0, $ RANGE=[xmin,xmax], $ LOCATION=[xmin,ymin,0], $ TICKLEN=0.02*(ymax-ymin), $ XCOORD_CONV=xs,YCOORD_CONV=ys;,ZCOORD_CONV=zs ; convert X ticks to exponential notation if necessary sWps.rXaxis->GetProperty, $ TICKVALUES=values sWps.rXtitle->GetProperty, UVALUE=title values = WV_RESCALE_AXIS(values, $ EXPONENT=Xexponent, $ SCALE_FACTOR=Xscale_factor, $ TITLE=title) IF (Xscale_factor NE 1) THEN BEGIN sWps.rXaxis->SetProperty, $ RANGE=[xmin,xmax]/Xscale_factor, $ LOCATION=[xmin/Xscale_factor,ymin,0], $ XCOORD_CONV=[xs[0],xs[1]*Xscale_factor], $ YCOORD_CONV=ys;,ZCOORD_CONV=zs sWps.rXtitle->SetProperty, STRINGS=title ENDIF ; change Y axis ranges & ticks sWps.rYaxis->SetProperty, $ HIDE=0, $ MAJOR=-1, $ RANGE=[ymin,ymax], $ LOCATION=[xmin,ymin,0], $ TICKLEN=0.02*(xmax-xmin), $ TICKVALUES=0, $ XCOORD_CONV=xs,YCOORD_CONV=ys;,ZCOORD_CONV=zs ; remove last tick mark on y-axis (that power-of-two is off the scale) ; sWps.rYaxis->GetProperty, $ ; MAJOR=major, $ ; TICKVALUES=tickvalues ; IF (MAX(tickvalues) EQ ymax) THEN BEGIN ; sWps.rYaxis->SetProperty, $ ; MAJOR=major-1, $ ; TICKVALUES=tickvalues[0:major-2] ; ENDIF ; change Z axis ranges & ticks sWps.rZaxis->SetProperty, $ RANGE=[zmin,zmax] ; convert Z ticks to exponential notation if necessary sWps.rZaxis->GetProperty, $ TICKVALUES=values ; use the Colorbartitle as the Z title values = WV_RESCALE_AXIS(values, $ SCALE_FACTOR=Zscale_factor, $ SCALE_STRING=Zscale_string, $ TITLE=colorbartitle) IF (Zscale_factor NE 1) THEN BEGIN sWps.rZaxis->SetProperty, $ RANGE=[zmin,zmax]/Zscale_factor ENDIF ; change ColorBar ticks sWps.rZaxis->GetProperty, $ TICKVALUES=tickvalues, $ TICKTEXT=Zticktext Zticktext->GetProperty,STRINGS=strings sWps.rColorBarTicktext->SetProperty, STRINGS=['',strings], $ LOCATIONS=0 tickvalues = [0,FIX(255.*(tickvalues*Zscale_factor-zmin)/(zmax-zmin))] sWps.rColorBar->SetProperty, $ MAJOR=N_ELEMENTS(tickvalues), $ TICKVALUES=tickvalues sWps.rColorBarTitle->SetProperty, STRINGS=colorbartitle ; change coord conversions for time series IF (oneD) THEN BEGIN ; find coord conversions sWps.rTimeSeries->GetProperty, $ XRANGE=xrange, $ YRANGE=yrange x0 = MIN(xrange,MAX=x1) y0 = MIN(yrange,MAX=y1) xstime = [-0.45 - FLOAT(x0)/(x1 - x0),1./(x1 - x0)] ystime = [0.1 - 0.4*FLOAT(y0)/(y1 - y0), 0.4/(y1 - y0)] ; change coord convert for time series sWps.rTimeSeries->SetProperty, $ XCOORD_CONV=xstime,YCOORD_CONV=ystime ; fix time series Y axis sWps.rTsYaxis->SetProperty, $ LOCATION=[xmin,y0,0], $ RANGE=[y0,y1], $ TICKLEN=0.02*(xmax-xmin), $ XCOORD_CONV=xstime,YCOORD_CONV=ystime ; convert time series Y axis to exponential notation if necessary sWps.rTsYaxis->GetProperty, $ TICKVALUES=values sWps.rTsYtitle->GetProperty, UVALUE=title values = WV_RESCALE_AXIS(values, $ SCALE_FACTOR=tYscale_factor, $ TITLE=title) IF (tYscale_factor NE 1) THEN BEGIN sWps.rTsYaxis->SetProperty, $ RANGE=[y0,y1]/tYscale_factor, $ LOCATION=[xmin,y0/tYscale_factor,0], $ YCOORD_CONV=[ystime[0],ystime[1]*tYscale_factor] sWps.rTsYtitle->SetProperty, STRINGS=title ENDIF ; add data for global wavelet spectrum (GWS) sWps.rGws->SetProperty, $ DATAX=*pY, $ DATAY=REVERSE(*pGws), $ MIN_VALUE=zmin, $ XCOORD_CONV=ys2,YCOORD_CONV=zs ; change scaling for GWS "Z" (actually Y) axis sWps.rZaxis->SetProperty, $ HIDE=0, $ RANGE=[zmin,zmax]/Zscale_factor, $ LOCATION=[ymax,zmin/Zscale_factor], $ TICKLEN=0.02*(ymax-ymin), $ XCOORD_CONV=ys2, $ YCOORD_CONV=[zs[0],zs[1]*Zscale_factor] ; put just the exponential notation on the Zaxis title sWps.rZtitle->SetProperty, STRINGS='Mean '+Zscale_string ; reverse direction of Y axis sWps.rYaxis->GetProperty, $ RANGE=range, $ TICKVALUES=tickvalues ; invert the axis values new_tickv = range[0]+range[1]-tickvalues ; convert values to powers-of-two dt = (*pX)[1] - (*pX)[0] power2_tickv = dt*(2d^tickvalues) ; check if exponential notation necessary? IF (N_ELEMENTS(Xexponent) EQ 1) THEN BEGIN sWps.rYtitle->GetProperty, $ UVALUE=ytitle_str power2_tickv = WV_RESCALE_AXIS(power2_tickv, $ EXPONENT=Xexponent, $ TITLE=ytitle_str) sWps.rYtitle->SetProperty, $ STRINGS=ytitle_str ENDIF ; fake the axis to construct the tick labels sWps.rYaxis->SetProperty, $ MAJOR=N_ELEMENTS(power2_tickv), $ TICKVALUES=power2_tickv ; get the newly-constructed labels sWps.rYaxis->GetProperty, $ TICKTEXT=ticktext ticktext->GetProperty,STRINGS=strings ; convert back to non-power-of-two tick values sWps.rYaxis->SetProperty, $ MAJOR=N_ELEMENTS(new_tickv), $ TICKVALUES=new_tickv ; but use the power-of-two tick labels ticktext->SetProperty, $ STRINGS=strings ENDIF ; oneD ; add data to contour plots n_levels = 15 c_value = INTERPOL([zmin,zmax],n_levels) c_color = BYTSCL(INDGEN(n_levels)) sWps.rLineContour->GetProperty, $ PLANAR=planar,UVALUE=top zvalues = TEMPORARY(zvalues) + 1e-2*(zmax-zmin) ; Pass in a scalar geomz in case /PLANAR is set (ignored if PLANAR=0). geomz = top ? zmax : zmin sWps.rLineContour->SetProperty, $ C_VALUE=c_value, $ DATA_VALUES=zvalues, $ GEOMX=*pX, GEOMY=*pY, GEOMZ=geomz, $ PLANAR=planar, $ XCOORD_CONV=xs, YCOORD_CONV=ys2, ZCOORD_CONV=zs sWps.rColorContour->GetProperty, $ PLANAR=planar,UVALUE=top ; Pass in a scalar geomz in case /PLANAR is set (ignored if PLANAR=0). geomz = top ? zmax : zmin sWps.rColorContour->SetProperty, $ C_VALUE=c_value, $ C_COLOR=c_color, $ DATA_VALUES=zvalues, $ GEOMX=*pX, GEOMY=*pY, GEOMZ=geomz, $ XCOORD_CONV=xs, YCOORD_CONV=ys2, ZCOORD_CONV=zs ; redraw significance level sWps.rSignifSheet->SetProperty, $ XCOORD_CONV=xs, YCOORD_CONV=ys2, ZCOORD_CONV=zs ; redraw text label sWps.rSignifText->SetProperty, $ XCOORD_CONV=xs, YCOORD_CONV=ys, ZCOORD_CONV=zs ; redraw significance contour sWps.rSignifContour->GetProperty, $ PLANAR=planar,UVALUE=top ; Pass in a scalar geomz in case /PLANAR is set (ignored if PLANAR=0). geomz = top ? zmax : zmin sWps.rSignifContour->SetProperty, $ DATA_VALUES=zvalues, $ GEOMX=*pX, GEOMY=*pY, GEOMZ=geomz, $ XCOORD_CONV=xs, YCOORD_CONV=ys2, ZCOORD_CONV=zs IF (N_ELEMENTS(*pPhase) GT 1) THEN BEGIN top = 255b phaseScale = BYTSCL(SQRT(ABS(*pPhase)), $ MIN=0, MAX=SQRT(!PI), TOP=top)+(255b-top) data = [[[phaseScale*0b+255b]],[[phaseScale]]] sWps.rPhaseImage->SetProperty, $ DATA=data, $ BLEND_FUNCTION=[3,1], $ INTERLEAVE=2 ENDIF ELSE BEGIN ; sWps.rSurface->SetProperty, $ ; TEXTURE_MAP=OBJ_NEW() sWps.rPhaseImage->SetProperty, $ DATA=BYTARR(2,2,2)+255b, $ BLEND_FUNCTION=[1,2] ENDELSE RETURN END ; wv_plot3d_redraw ;-------------------------------------------------------------------- ;Purpose: create objects related to the WPS. ; FUNCTION wv_plot3d_init,array,x,y, $ TITLE=title, $ XTITLE=xtitle, $ YTITLE=ytitle, $ XUNITS=xunits, $ YUNITS=yunits, $ UNITS=units, $ DRAW_XSIZE=draw_xsize, $ DRAW_YSIZE=draw_ysize, $ SURFACE_STYLE=surface_style COMPILE_OPT strictarr, hidden ; Set all the defaults dim = SIZE(array, /DIMENSIONS) oneD = SIZE(array, /N_DIM) EQ 1 IF (N_ELEMENTS(x) LT 1) THEN x = LINDGEN(dim[0]) IF (N_ELEMENTS(y) LT 1) THEN y = oneD ? 0 : LINDGEN(dim[1]) IF (N_ELEMENTS(xtitle) LE 0) THEN xtitle = 'X' IF (N_ELEMENTS(ytitle) LE 0) THEN ytitle = 'Y' IF (N_ELEMENTS(xunits) LE 0) THEN xunits = '' IF (N_ELEMENTS(yunits) LE 0) THEN yunits = '' IF (N_ELEMENTS(units) LE 0) THEN units = '' IF (N_ELEMENTS(surface_style) LE 0) THEN surface_style = 3 ; Create a view rView = OBJ_NEW('IDLgrView', $ COLOR = [208, 208, 208], $ ; COLOR = [128, 128, 128], $ VIEWPLANE_RECT = [-1.,-1.,2.,2.]);, $ ; EYE=16, $ ; ZCLIP=[15,-15]) ; Create models rTop = OBJ_NEW('IDLgrModel') rGroup = OBJ_NEW('IDLgrModel') ; Create dummy container to make it easier to destroy objects rContainer = OBJ_NEW('IDL_Container') rFont = OBJ_NEW('IDLgrFont') rContainer->Add, rFont ; create axes extra = {exact:1, $ ; keywords for all axes hide:1, $ minor:1, $ tickdir:1} ; Xaxis xtitle_str = xtitle IF (NOT oneD) THEN xtitle_str = 'X Scale' rXtitle = OBJ_NEW('IDLgrText', xtitle_str, $ /ENABLE_FORMATTING, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2, $ UVALUE=xtitle_str) rContainer->Add, rXtitle rXaxis = OBJ_NEW('IDLgrAxis',0, $ _EXTRA=extra,TITLE=rXtitle) rXaxis->GetProperty, TICKTEXT=ticktext ticktext->SetProperty, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2 ; Yaxis IF (oneD) THEN BEGIN ytitle_str = 'Scale' IF (xunits NE '') THEN ytitle_str = ytitle_str + ' (' + xunits + ')' ENDIF ELSE BEGIN ytitle_str = 'Y Scale' ENDELSE rYtitle = OBJ_NEW('IDLgrText', ytitle_str, $ /ENABLE_FORMATTING, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2, $ UVALUE=ytitle_str) rContainer->Add, rYtitle rYaxis = OBJ_NEW('IDLgrAxis',1, $ _EXTRA=extra,TITLE=rYtitle) rYaxis->GetProperty, TICKTEXT=ticktext ticktext->SetProperty, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2 ; Zaxis ztitle_str = '' rZtitle = OBJ_NEW('IDLgrText', ztitle_str, $ /ENABLE_FORMATTING, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2, $ UVALUE=ztitle_str) rContainer->Add, rZtitle rZaxis = OBJ_NEW('IDLgrAxis',1, $ _EXTRA=extra, $ TEXTPOS=1, $ TITLE=rZtitle) rContainer->Add, rZaxis rZaxis->GetProperty, TICKTEXT=ticktext ticktext->SetProperty, $ /ENABLE_FORMATTING, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2 ; Create color palettes FOR WPS. gray = REPLICATE(128b,256) rGrayPalette = OBJ_NEW('IDLgrPalette', $ gray, gray, gray) rContainer->Add, rGrayPalette rColorPalette = OBJ_NEW('IDLgrPalette') rColorPalette->LOADCT, 39 ; "rainbow+white" rContainer->Add, rColorPalette rPhaseImage = OBJ_NEW('IDLgrImage', $ HIDE=0) rContainer->Add, rPhaseImage ; Create surface plot rSurface = OBJ_NEW('IDLgrSurface', $ COLOR=[255,255,255], $ EXTENDED=0, $ HIDE=0, $ PALETTE=rColorPalette, $ SHADING=1, $ SHADE_RANGE=[0b,255b], $ SHOW_SKIRT=0, $ STYLE=surface_style-1, $ UVALUE=0) ; Create the filled contour version OF the WPS. rColorContour = OBJ_NEW('IDLgrContour', $ DATA_VALUES=FLTARR(2,2), $ FILL=0, $ HIDE=1, $ PALETTE=rColorPalette, $ UVALUE=0) ; Create the line contour version OF the WPS. rLineContour = OBJ_NEW('IDLgrContour', $ C_LINESTYLE=0, $ COLOR=[255,255,255], $ DATA_VALUES=FLTARR(2,2), $ HIDE=1, $ FILL=0, $ UVALUE=0) ; Create the significance polygon sheet rSignifSheet = OBJ_NEW('IDLgrPolygon', $ /HIDE, $ PALETTE=rColorPalette) rSignifText = OBJ_NEW('IDLgrText', $ /ENABLE_FORMATTING, $ FONT=rFont, $ /HIDE, $ PALETTE=rColorPalette, $ RECOMPUTE_DIMENSIONS=2) ; Create the line contour version OF the WPS. rSignifContour = OBJ_NEW('IDLgrContour', $ C_LINESTYLE=0, $ COLOR=[255,255,255], $ DATA_VALUES=FLTARR(2,2), $ HIDE=1, $ FILL=0, $ C_THICK=[2], $ UVALUE=0) ; Add objects to the model rGroup->Add, rSurface rGroup->Add, rXaxis rGroup->Add, rYaxis rGroup->Add, rColorContour rGroup->Add, rLineContour rGroup->Add, rSignifSheet rGroup->Add, rSignifText rGroup->Add, rSignifContour ; Create the 1D time series rTimeSeries = 0 rTsYaxis = 0 rTsYtitle = 0 rGws = 0 rTsModel = 0 rGwsModel = 0 IF oneD THEN BEGIN ; oneD rTimeSeries = OBJ_NEW('IDLgrPlot',x,array, $ HIDE=0, $ THICK=2) rTsYtitle = OBJ_NEW('IDLgrText', ytitle, $ /ENABLE_FORMATTING, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2, $ UVALUE=ytitle) rContainer->Add, rTsYtitle rTsYaxis = OBJ_NEW('IDLgrAxis',1, $ HIDE=0, $ /EXACT, $ MINOR=1, $ TITLE=rTsYtitle) rTsYaxis->GetProperty, TICKTEXT=ticktext ticktext->SetProperty, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2 rTsModel = OBJ_NEW('IDLgrModel',LIGHTING=0) rTsModel->Add, rTimeSeries rTsModel->Add, rTsYaxis rTsModel->Rotate, [1,0,0], 90 ; bend up rTsModel->Translate, 0, 0.57, 0 ; move farther back rGws = OBJ_NEW('IDLgrPlot', $ HIDE=0, $ THICK=2) rGwsModel = OBJ_NEW('IDLgrModel',LIGHTING=0) rGwsModel->Add, rGws rGwsModel->Rotate, [1,0,0], 90 rGwsModel->Rotate, [0,0,1], -90 rGwsModel->Translate, 0.62, 0.1, 0 ; move farther to the right rGwsModel->Add, rZaxis rGroup->Add, rTsModel rGroup->Add, rGwsModel ENDIF ; oneD ; Place the model in the view. rTop->Add, rGroup rView->Add, rTop ; Add lights rAmbientLight = OBJ_NEW('IDLgrLight', TYPE=0, INTENSITY=1) rTop->Add, rAmbientLight rDirectionalLight = OBJ_NEW('IDLgrLight', $ LOCATION=[0.4,0.4,1], $ INTENSITY=1, $ TYPE=2) rTop->Add,rDirectionalLight ; Add colorbar legend. rColorBarTitle = OBJ_NEW('IDLgrText', 'Power', $ /ENABLE_FORMATTING, $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2, $ UVALUE='') rContainer->Add, rColorBarTitle rColorBarTicktext = OBJ_NEW('IDLgrText',[' ',' '], $ FONT=rFont, $ RECOMPUTE_DIMENSIONS=2) rContainer->Add, rColorBarTicktext maxLen = 256 xs = [-0.45, 1.0 / maxLen] ys = [-.74, 1.0 / maxLen] zs = [0.0, 1.0 / maxLen] rColorBar = OBJ_NEW('IDLgrColorBar', $ DIMENSIONS=[256,16], $ HIDE=0, $ MAJOR=2, $ MINOR=0, $ PALETTE=rColorPalette, $ SHOW_AXIS=2, $ /SHOW_OUTLINE, $ /THREED, $ TICKLEN=4, $ TICKTEXT=rColorBarTicktext, $ TITLE=rColorBarTitle, $ XCOORD_CONV=xs, YCOORD_CONV=ys);, ZCOORD_CONV=zs) rGroup->Add, rColorbar ; Rotate to a nice perspective FOR first draw. rGroup->ROTATE, [0,0,1], 25 rGroup->ROTATE, [1,0,0], -30 rTrackballRotate = OBJ_NEW('Trackball', $ [draw_xsize/2, draw_ysize/2.], $ draw_xsize/2.) rContainer->Add, rTrackballRotate rTrackballScale= OBJ_NEW('Trackball', $ [draw_xsize/2, draw_ysize/2.], $ draw_xsize/2.,MOUSE=2) rContainer->Add, rTrackballScale rTrackballTranslate = OBJ_NEW('Trackball', $ [draw_xsize/2, draw_ysize/2.], $ draw_xsize/2.,MOUSE=4) rContainer->Add, rTrackballTranslate rView->SetProperty, UVALUE= $ {rView:rView, $ rTop:rTop, $ rGroup:rGroup, $ rContainer:rContainer, $ rFont:rFont, $ rXaxis:rXaxis, $ rYaxis:rYaxis, $ rZaxis:rZaxis, $ rXtitle:rXtitle, $ rYtitle:rYtitle, $ rZtitle:rZtitle, $ rLineContour:rLineContour, $ rColorContour:rColorContour, $ rSignifSheet:rSignifSheet, $ rSignifText:rSignifText, $ rSignifContour:rSignifContour, $ rPhaseImage:rPhaseImage, $ rSurface:rSurface, $ rTimeSeries:rTimeSeries, $ rGws:rGws, $ rTsModel:rTsModel, $ rGwsModel:rGwsModel, $ rTsYaxis:rTsYaxis, $ rTsYtitle:rTsYtitle, $ rColorPalette:rColorPalette, $ rGrayPalette:rGrayPalette, $ rColorBar:rColorBar, $ rColorBarTitle:rColorBarTitle, $ rColorBarTicktext:rColorBarTicktext, $ rTrackballRotate:rTrackballRotate, $ rTrackballScale:rTrackballScale, $ rTrackballTranslate:rTrackballTranslate, $ rDirectionalLight:rDirectionalLight} ; Create the info structure meanArray = TOTAL(array)/N_ELEMENTS(array) varArray = VARIANCE(array) rState = { $ base_size: [0L,0L], $ file_path:'', $ oneD: oneD, $ pData: PTR_NEW(array - meanArray), $ pXdata: PTR_NEW(x), $ pYdata: PTR_NEW(y), $ pColortable: PTR_NEW(/ALLOCATE_HEAP), $ meanArray: meanArray, $ varArray: varArray, $ var_zscale: 0.0, $ xtitle:xtitle, $ xunits:xunits, $ ytitle:ytitle, $ yunits:yunits, $ title:title, $ units:units, $ WPS_drag_quality: 1b, $ btndown: 0b, $ draw_xsize: draw_xsize, $ draw_ysize: draw_ysize, $ rView: rView, $ rContainer: rContainer, $ rPrinter: OBJ_NEW(), $ rClipboard: OBJ_NEW(), $ rVRML: OBJ_NEW(), $ pWavelet: PTR_NEW(/ALLOCATE_HEAP), $ pX: PTR_NEW(/ALLOCATE_HEAP), $ pY: PTR_NEW(/ALLOCATE_HEAP), $ pZ: PTR_NEW(/ALLOCATE_HEAP), $ pGws: PTR_NEW(/ALLOCATE_HEAP), $ pPhase: PTR_NEW(0) $ } RETURN, rState END ; wv_plot3d_init ;-------------------------------------------------------------------- FUNCTION wv_plot3d_location, dataxyz, inside, $ pX, pY, pZ, pW, oneD COMPILE_OPT strictarr, hidden CASE (inside) OF -1: BEGIN CASE STRLOWCASE(!VERSION.OS_FAMILY) OF 'macos': location = 'Mouse button to rotate, ' + $ '