;+ ; NAME: ; spheretool_event ; ; PURPOSE: ; Event handler for spheretool. ; ; CATEGORY: ; Digital holographic microscopy ; ; CALLING SEQUENCE: ; Internal routine. Not intended for independent use. ; spheretool_event, ev ; ; INPUTS: ; ev: the GUI event that triggered the call. ; ; REFERENCE: ; S. Lee, Y. Roichman, G. Yi, S. Kim, S. Yang, A. van Blaaderen, ; P. van Oostrum and D. G. Grier, ; Chararacterizing and tracking ; single colloidal particles with video holographic microscopy, ; Optics Express 15, 18275-18282 (2007) ; ; MODIFICATION HISTORY: ; 03/18/2009 David G. Grier, New York University. Separated from SPHERETOOL. ; 03/18/2009 DGG: Implemented ROI display. ; 03/18/2009 DGG: Added support for particle extinction coefficient. ; Removed support for coherence parameter BETA. Pass state ; pointer rather than entire state structure. ; ; LICENSE ; ; This program is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License as ; published by the Free Software Foundation; either version 2 of the ; License, or (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ; General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, write to the Free Software ; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA ; 02111-1307 USA ; ; If the Internet and WWW are still functional when you are using ; this, you shold be able to access the GPL here: ; http://www.gnu.org/copyleft/gpl.html ;- pro spheretool_event, ev compile_opt idl2, hidden ; The base widget's uvalue is the structure containing all the ; information about the program's state. WIDGET_CONTROL, ev.TOP, GET_UVALUE = s ; Clicking on a tab is handled automatically. Nothing to do, so ; move along. if (ev.ID eq (*s).w.wtab) then return ; Other widgets can give us something to do. WIDGET_CONTROL, ev.ID, GET_UVALUE = uval sz = size((*s).p.a, /DIMENSIONS) CASE uval of 'IMAGE' : begin if (ev.press) then begin !x.s = (*s).geom.xs !y.s = (*s).geom.ys val = convert_coord(ev.x, ev.y, /device, /to_data) (*s).p.rc = val[0:1] if (*s).p.fixed[6] then begin (*s).p.aa = aziavg(deinterlace((*s).p.a), center = (*s).p.rc) (*s).p.daa = azistd(deinterlace((*s).p.a), center = (*s).p.rc) endif else begin (*s).p.aa = aziavg((*s).p.a, center = (*s).p.rc) (*s).p.daa = azistd((*s).p.a, center = (*s).p.rc) endelse WIDGET_CONTROL, (*s).w.wxc, SET_VALUE = val[0] WIDGET_CONTROL, (*s).w.wyc, SET_VALUE = val[1] endif end 'BUTTONS' : begin (*s).p.fixed[ev.value] = ev.select end 'AP' : begin WIDGET_CONTROL, (*s).w.wap, GET_VALUE = val (*s).p.ap = val end 'ZP' : begin WIDGET_CONTROL, (*s).w.wzp, GET_VALUE = val (*s).p.zp = val end 'NP' : begin WIDGET_CONTROL, (*s).w.wnp, GET_VALUE = val (*s).p.np = val end 'KP': begin WIDGET_CONTROL, (*s).w.wkp, GET_VALUE = val (*s).p.kp = val end 'NM' : begin WIDGET_CONTROL, (*s).w.wnm, GET_VALUE = val (*s).p.nm = val end 'ALPHA': begin WIDGET_CONTROL, (*s).w.walpha, GET_VALUE = val (*s).p.alpha = val end 'XC': begin WIDGET_CONTROL, (*s).w.wxc, GET_VALUE = val (*s).p.rc[0] = val if (*s).p.fixed[6] then begin (*s).p.aa = aziavg(deinterlace((*s).p.a), center = (*s).p.rc) (*s).p.daa = azistd(deinterlace((*s).p.a), center = (*s).p.rc) endif else begin (*s).p.aa = aziavg((*s).p.a, center = (*s).p.rc) (*s).p.daa = azistd((*s).p.a, center = (*s).p.rc) endelse end 'YC': begin WIDGET_CONTROL, (*s).w.wyc, GET_VALUE = val (*s).p.rc[1] = val if (*s).p.fixed[6] then begin (*s).p.aa = aziavg(deinterlace((*s).p.a), center = (*s).p.rc) (*s).p.daa = azistd(deinterlace((*s).p.a), center = (*s).p.rc) endif else begin (*s).p.aa = aziavg((*s).p.a, center = (*s).p.rc) (*s).p.daa = azistd((*s).p.a, center = (*s).p.rc) endelse end 'RAD': begin WIDGET_CONTROL, (*s).w.wrad, GET_VALUE = val (*s).p.rad = val end 'LAMBDA': begin WIDGET_CONTROL, (*s).w.wlambda, GET_VALUE = val (*s).p.lambda = val end 'MPP': begin WIDGET_CONTROL, (*s).w.wmpp, GET_VALUE = val (*s).p.mpp = val end 'IMAGEEVENT': begin if ev.press then begin print, "Fitting to Mie scattering theory ..." WIDGET_CONTROL, /HOURGLASS rc = (*s).p.rc rad = (*s).p.rad x0 = round(rc[0] - rad) > 0 x1 = round(rc[0] + rad) < sz[0]-1 y0 = round(rc[1] - rad) > 0 y1 = round(rc[1] + rad) < sz[1]-1 ac = (*s).p.a[x0:x1, y0:y1] nx = x1 - x0 + 1 ny = y1 - y0 + 1 xp = rc[0] - x0 - nx/2. yp = rc[1] - y0 - ny/2. pin = [xp, yp, (*s).p.zp, (*s).p.ap, (*s).p.np, (*s).p.alpha, (*s).p.nm] if (*s).p.kp gt 0. or (*s).p.km gt 0. then $ pin = [pin, (*s).p.kp, (*s).p.km] if (*s).p.fixed[6] then begin plotimage, bytscl(deinterlace(ac)), /iso pout = fitspheredhm(ac, pin, $ lambda = (*s).p.lambda, $ mpp = (*s).p.mpp, $ deinterlace = y0, $ fixap = (*s).p.fixed[0], $ fixzp = (*s).p.fixed[1], $ fixnp = (*s).p.fixed[2], $ fixnm = (*s).p.fixed[3], $ fixalpha = (*s).p.fixed[4], $ gpu = (*s).p.gpu) endif else begin plotimage, bytscl(ac), /iso pout = fitspheredhm(ac, pin, $ lambda = (*s).p.lambda, $ mpp = (*s).p.mpp, $ fixap = (*s).p.fixed[0], $ fixzp = (*s).p.fixed[1], $ fixnp = (*s).p.fixed[2], $ fixnm = (*s).p.fixed[3], $ fixalpha = (*s).p.fixed[4], $ gpu = (*s).p.gpu) endelse print, pout (*s).p.rc = [x0+nx/2., y0+ny/2.] + pout[0,0:1] ; XXX WIDGET_CONTROL, (*s).w.wxc, SET_VALUE = (*s).p.rc[0] WIDGET_CONTROL, (*s).w.wyc, SET_VALUE = (*s).p.rc[1] (*s).p.zp = pout[0,2] WIDGET_CONTROL, (*s).w.wzp, SET_VALUE = (*s).p.zp (*s).p.ap = pout[0,3] WIDGET_CONTROL, (*s).w.wap, SET_VALUE = (*s).p.ap (*s).p.np = pout[0,4] WIDGET_CONTROL, (*s).w.wnp, SET_VALUE = (*s).p.np (*s).p.alpha = pout[0,5] WIDGET_CONTROL, (*s).w.walpha, SET_VALUE = (*s).p.alpha (*s).p.nm = pout[0,6] WIDGET_CONTROL, (*s).w.wnm, SET_VALUE = (*s).p.nm (*s).p.aa = aziavg((*s).p.a, center = (*s).p.rc) (*s).p.daa = azistd((*s).p.a, center = (*s).p.rc) WIDGET_CONTROL, HOURGLASS = 0 endif end 'SAVEPROGRAM': begin spheretool_saveroutine, s end 'SAVEVALUES': begin fn = DIALOG_PICKFILE(/WRITE, /OVERWRITE_PROMPT, $ TITLE = "Save Values", FILTER = "*.gdf", $ DEFAULT_EXTENSION = "gdf") if strlen(fn) ge 1 then begin if (*s).p.fit[1,0] gt 0. then $ write_gdf, (*s).p.fit, fn, /ASCII $ else begin write_gdf, [(*s).p.rc, $ (*s).p.zp, $ (*s).p.ap, $ (*s).p.np, $ (*s).p.kp, $ (*s).p.alpha, $ (*s).p.nm, $ (*s).p.km], fn, /ASCII endelse endif end 'QUIT' : begin WIDGET_CONTROL, ev.TOP, /DESTROY return end ELSE: print, 'Event type not yet implemented' ENDCASE ; Process the present image according to the present settings. ; Show updated region of interest WIDGET_CONTROL, (*s).w.wimage, GET_VALUE = ndx wset, ndx set_plot, 'z' plotimage, bytscl((*s).p.a, top=253), /iso rc = (*s).p.rc rad = (*s).p.rad x0 = round(rc[0] - rad) > 0 x1 = round(rc[0] + rad) < sz[0]-1 y0 = round(rc[1] - rad) > 0 y1 = round(rc[1] + rad) < sz[1]-1 plots, rc[0], rc[1], psym=circ() plots, [x0,x1,x1,x0,x0], [y0,y0,y1,y1,y0], linestyle=3, color=254 image = tvrd() set_plot, 'x' tv, image ; show update DHM profile WIDGET_CONTROL, (*s).w.wprofile, GET_VALUE = ndx wset, ndx rho = findgen(n_elements((*s).p.aa)) b = spheredhmprofile(rho, (*s).p.zp, (*s).p.ap, dcomplex((*s).p.np, (*s).p.kp), $ dcomplex((*s).p.nm, (*s).p.km), (*s).p.alpha, $ lambda = (*s).p.lambda, mpp = (*s).p.mpp) set_plot, 'z' plot, (*s).p.aa, thick=2, xtitle='r [pixel]', ytitle='B(r)', $ xrange = [0,(*s).p.rad], /xstyle oplot, (*s).p.aa + (*s).p.daa, linestyle=2 oplot, (*s).p.aa - (*s).p.daa, linestyle=2 oplot, rho, b, color=254 image = tvrd() set_plot, 'x' tv, image WIDGET_CONTROL, ev.TOP, SET_UVALUE=s end