;+ ; NAME: ; spheretool ; ; PURPOSE: ; Interactively find reasonable fitting parameters for digital ; holographic microscopy images of colloidal spheres. ; ; CATEGORY: ; Digital holography; microscopy ; ; CALLING SEQUENCE: ; IDL> spheretool, a ; ; INPUTS: ; a: DHM image of a sphere normalized by a background image. ; ; KEYWORD PARAMETERS; ; lambda: vacuum wavelength of light [micrometers] ; Default: 0.6328 (He-Ne) ; ; mpp: length scale calibration [micrometers/pixel] ; Default: 0.135 ; ; nm: complex refractive index of medium. ; Default: 1.3326 (water) ; ; SIDE EFFECTS: ; Opens an interactive widget-based application. ; ; PROCEDURE: ; Computes DHM image using results for the Mie scattering of ; coherent light by uniform spheres. ; Calls SPHEREDHMPROFILE and FITSPHEREDHM, ; which in turn rely on SPHEREFIELD. ; ; 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) ; ; INSTRUCTIONS: ; Click on center of sphere's image in IMAGE window. ; Click on PROFILE tab to examine the hologram's radial profile. ; Adjust the radius, refractive index, axial displacement and ; amplitude to get a good fit. Click on plot to run ; least-squares fit. ; ; MODIFICATION HISTORY: ; Written 06/11/2007 by David G. Grier, New York University. ; 06/13/2007 DGG: Save parameters, minimal idiot proofing, minimal ; documentation. ; 06/18/2007 DGG: Added COHERENCE slider. ; 06/19/2007 DGG: Added standard deviations to the radial plot ; 11/03/2007 DGG: Major additions and internal code cleanup: ; IMAGE tab: added XC, YC, and LAMBDA. ; PROFILE tab: Reorganized widgets. ; Implemented fitting with FITSPHEREDHM. Fit starts with ; click on profile plot. Added checkboxes to fix parameters ; during fitting. Widgets updated with fit values. ; Corrected vacuum wavelength for HeNe laser. Removed unused ; internal variables. ; 02/08/2008 DGG: Added "Save Procedure" to File menu. ; 04/16/2008 DGG: Added MPP keyword. Updated documentation. ; 10/08/2008 DGG: Corrected GUI action of XC, YC and LAMBDA widgets. ; 01/15/2009 DGG: Revised cropping code to allow for spheres closer ; than RAD to the edge of the image. ; 03/18/2009 DGG: Added MPP widget to image tab. ; 03/18/2009 DGG: Code reorganization. Separate into component ; files. ; 03/18/2009 DGG: Support for complex refractive indexes ; 03/20/2009 DGG: Added automatic GPU support. Added COMPILE_OPT. ; Pass pointer to state variable rather than the entire 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, a, nm = nm, lambda = lambda, mpp = mpp compile_opt idl2 width = 640 height = 480 if n_params() ne 1 then begin message, "USAGE: IDL> spheretool2, a", /inf message, "A must be a normalized DHM image.", /inf return endif sz = size(a) if sz[0] ne 2 then begin message, "USAGE: IDL> spheretool2, a", /inf message, "A must be a two-dimensional normalized DHM image", /inf return endif aa = aziavg(a) daa = azistd(a) xc = sz[1]/2. yc = sz[2]/2. rad = floor(xc < yc) fit = dblarr(2,7) ; p contains all the parameters used by SPHEREDHM ; Storing them here avoids the need for common blocks, ; and thus allows for multiple instances of SPHERETOOL. p = {a: a, $ ; the image aa: aa, $ ; azimuthally averaged image daa: daa, $ ; azimuthal standard deviation fit: fit, $ ; results of fits rc: [xc,yc], $ ; in-plane center [pixels] rad: rad, $ ; radius of ROI lambda: 0.632816d, $ ; wavelength of light [micrometers] (HeNe) mpp: 0.135d, $ ; length calibration [micrometers/pixel] fixed: [0,0,0,1,1,1,0], $ ; flags for fixed parameters zp: 100.d, $ ; axial position [pixels] ap: 1.d, $ ; particle radius [micrometers] np: 1.5d, $ ; particle refractive index kp: 0.d, $ ; particle extinction coefficient nm: 1.3326d, $ ; medium refractive index (water) km: 0.d, $ ; medium extinction coefficient alpha: 1.d, $ ; illumination amplitude gpu: 0} ; gpu acceleration flag p.gpu = spheretool_gpu_detect() if n_elements(nm) eq 1 then begin p.nm = real_part(nm) p.km = imaginary(km) endif if n_elements(lambda) eq 1 then $ p.lambda = double(lambda) if n_elements(mpp) eq 1 then $ p.mpp = double(mpp) red = indgen(255) green = red blue = red red[254] = 0 blue[254] = 0 tvlct, red, green, blue w = spheretool_widgets(p, width, height) WIDGET_CONTROL, w.base, /REALIZE ; show image with region of interest WIDGET_CONTROL, w.wimage, GET_VALUE = ndx wset, ndx plotimage, bytscl(p.a, top=253), /iso plots, p.rc[0], p.rc[1], psym=circ() x0 = xc - rad > 0 x1 = xc + rad < sz[1] - 1 y0 = yc - rad > 0 y1 = yc + rad < sz[2] - 1 plots, [x0,x1,x1,x0,x0], [y0,y0,y1,y1,y0], linestyle=3, color=254 geom = {xs:!x.s, ys:!y.s} ; show radial profile WIDGET_CONTROL, w.wprofile, GET_VALUE = ndx wset, ndx rho = findgen(100) b = spheredhmprofile(rho, p.zp, p.ap, dcomplex(p.np, p.kp), $ dcomplex(p.nm, p.km), p.alpha, $ lambda = p.lambda, mpp = p.mpp) plot, p.aa, thick = 2, $ xtitle = 'r [pixel]', ytitle = 'B(r)', $ xrange=[0, p.rad], /xstyle oplot, rho, b, color = 254 ; program state variables s = {w:w, geom:geom, p:p} ps = PTR_NEW(s, /NO_COPY) ; transfer state variables to callback routine to process events WIDGET_CONTROL, w.base, SET_UVALUE = ps, /NO_COPY ; process events XMANAGER, 'spheretool', w.base, /NO_BLOCK, CLEANUP='spheretool_cleanup' end