; docformat = 'rst' ;+ ; Create a thumbnail image of a simple visualization of the data. The ; visualization type is guessed based on the dimensions of the data. ;- ;+ ; Create a line plot. ; ; :Returns: ; bytarr(3, m, n) or -1L ; ; :Params: ; data : in, required, type=numeric array ; data to visualize ; ; :Keywords: ; valid : out, optional, type=boolean ; set to a named variable to get status of visualization; if no valid ; visualization type could be found, -1L is returned ;- function mg_thumbnail_lineplot, data, valid=valid compile_opt strictarr ; min and max size of the output image maxDimSize = 100L minDimSize = 10L ; goal is to make curve in output have a mean absolute value of the derivative ; of 1 (because that makes differences in the slope easiest to see) mDeriv = mean(abs(deriv(data))) xrange = n_elements(data) - 1L yrange = max(data, min=minData) - minData ; calculate output dimensions, making sure the dimensions fall in the range ; of minDimSize...maxDimSize dims = [xrange, yrange * mDeriv] dims = long(dims / float(max(dims)) * maxDimSize) dims = dims > minDimSize < maxDimSize view = obj_new('IDLgrView') model = obj_new('IDLgrModel') view->add, model plot = obj_new('IDLgrPlot', data, color=[0, 0, 255]) model->add, plot ; use most of the view: -0.9...0.9 for both x and y plot->getProperty, xrange=xr, yrange=yr xc = mg_linear_function(xr, [-0.9, 0.9]) yc = mg_linear_function(yr, [-0.9, 0.9]) if (total(finite(yc)) ne 2L) then begin yc = mg_linear_function([yr[0] - 1, yr[0] + 1], [-0.9, 0.9]) endif plot->setProperty, xcoord_conv=xc, ycoord_conv=yc buffer = obj_new('IDLgrBuffer', dimensions=dims) buffer->draw, view buffer->getProperty, image_data=im obj_destroy, [buffer, view] return, im end ;+ ; Create a contour plot. ; ; :Returns: ; bytarr(3, m, n) or -1L ; ; :Params: ; data : in, required, type=numeric array ; data to visualize ; ; :Keywords: ; valid : out, optional, type=boolean ; set to a named variable to get status of visualization; if no valid ; visualization type could be found, -1L is returned ;- function mg_thumbnail_contourplot, data, valid=valid compile_opt strictarr maxDimSize = 100L minDimSize = 10L ; preserve aspect ration but make sure the dimensions fall in the range ; minDimSize...maxDimSize sz = size(data, /structure) dims = sz.dimensions[0:1] dims = long(dims / float(max(dims)) * maxDimSize) dims = dims > minDimSize < maxDimSize view = obj_new('IDLgrView') model = obj_new('IDLgrModel') view->add, model nLevels = 20 contour = obj_new('IDLgrContour', data, $ planar=1, $ geomz=0.0, $ n_levels=nLevels, $ c_color=bytscl(bindgen(nLevels)), $ /fill) model->add, contour ; use most of the view: -0.9...0.9 for both x and y contour->getProperty, xrange=xr, yrange=yr xc = mg_linear_function(xr, [-1.0, 1.0]) yc = mg_linear_function(yr, [-1.0, 1.0]) contour->setProperty, xcoord_conv=xc, ycoord_conv=yc buffer = obj_new('IDLgrBuffer', dimensions=dims) buffer->draw, view buffer->getProperty, image_data=im obj_destroy, [buffer, view] return, im end ;+ ; Create a volume visualization. ; ; :Returns: ; bytarr(3, m, n) or -1L ; ; :Params: ; data : in, required, type=numeric array ; date to visualize ; ; :Keywords: ; valid : out, optional, type=boolean ; set to a named variable to get status of visualization; if no valid ; visualization type could be found, -1L is returned ;- function mg_thumbnail_volumeplot, data, valid=valid compile_opt strictarr maxDimSize = 100L minDimSize = 10L ; make a square display since the view dimensions don't correspond to data ; dimensions for a rotated volume dims = [maxDimSize, maxDimSize] view = obj_new('IDLgrView') model = obj_new('IDLgrModel') view->add, model vol = obj_new('IDLgrVolume', data) model->add, vol ; use less of the view for a 3D object: -0.7...0.7 for x, y, and z vol->getProperty, xrange=xr, yrange=yr, zrange=zr xc = mg_linear_function(xr, [-0.7, 0.7]) yc = mg_linear_function(yr, [-0.7, 0.7]) zc = mg_linear_function(zr, [-0.7, 0.7]) vol->setProperty, xcoord_conv=xc, ycoord_conv=yc, zcoord_conv=zc ; who knows what orientation is best: try this one model->rotate, [1, 0, 0], -90 model->rotate, [0, 1, 0], 30 model->rotate, [1, 0, 0], 30 buffer = obj_new('IDLgrBuffer', dimensions=dims) buffer->draw, view buffer->getProperty, image_data=im obj_destroy, [buffer, view] return, im end ;+ ; Resize image to correct dimensions while preserving the aspect ratio. ; ; :Returns: ; bytarr(3, m, n) or -1L ; ; :Params: ; data : in, required, type=numeric array ; data to visualize ; ; :Keywords: ; valid : out, optional, type=boolean ; set to a named variable to get status of visualization; if no valid ; visualization type could be found, -1L is returned ;- function mg_thumbnail_image, data, valid=valid compile_opt strictarr maxDimSize = 100L minDimSize = 10L sz = size(data, /structure) ind = where(sz.dimensions[0:sz.n_dimensions - 1L] le 4, count, complement=cind) ; this would be odd: quit if there is not just one dimension with size 1...4 if (count ne 1) then begin valid = 0B return, -1L endif ; make the image pixel interleave im = transpose(data, [ind[0], cind]) ; calculate dimensions that preserve aspect ratio, but are in the range ; minDimSize...maxDimSize origDims = [sz.dimensions[cind[0]], sz.dimensions[cind[1]]] dims = long(origDims / float(max(origDims)) * maxDimSize) ; only resize to smaller, never bigger doResize = total(dims gt origDims) eq 0 dims = dims > minDimSize < maxDimSize if (doResize) then begin im = congrid(im, sz.dimensions[ind[0]], dims[0], dims[1]) endif return, im end ;+ ; Dispatches data to proper helper routine to produce a simple thumbnail ; visualization of the data and returns the result as a true color image. ; ; :Returns: ; bytarr(3, m, n) or -1L ; ; :Params: ; data : in, required, type=numeric array ; data to visualize ; ; :Keywords: ; valid : out, optional, type=boolean ; set to a named variable to get status of visualization; if no valid ; visualization type could be found, -1L is returned ;- function mg_thumbnail, data, valid=valid compile_opt strictarr sz = size(data, /structure) ; set to not valid for any of the following types or sizes valid = 0B ; invalid types/sizes if (sz.type eq 7) then return, -1L if (sz.type eq 8) then return, -1L if (sz.type eq 11) then return, -1L if (sz.n_dimensions eq 0) then return, -1L if (sz.n_dimensions gt 3) then return, -1L if (sz.n_elements lt 3) then return, -1L valid = 1B ; valid types/sizes case sz.n_dimensions of 1: return, mg_thumbnail_lineplot(data, valid=valid) 2: return, mg_thumbnail_contourplot(data, valid=valid) 3: begin ind = where(sz.dimensions[0:sz.n_dimensions - 1L] le 4, count) ; if not exactly one small dimension then assume volume if (count ne 1) then return, mg_thumbnail_volumeplot(data, valid=valid) ; if there are small dimensions then assume an image return, mg_thumbnail_image(data, valid=valid) end endcase end