;+ ; NAME: ; qImage_cw_ZUpdate ; PURPOSE: ; Updates fields in widget that need to be updated every time the selected ; box changes. This includes the Z-value widgets (Z-min, Z-max, Z-avg, Z-std) ; and the centroid widgets X-com, Y-com ; CATEGORY: ; Compound widget qImage_cw ; CALLING SEQUENCE: PRO qImage_cw_ZUpdate, state ; INPUTS: ; state array[1]; type: structure ; pImage state structure ; OUTPUTS: ; (none) ; INCLUDE: @compile_opt.pro ; On error, return to caller ; CALLS: ; BadValue, qImage_cw_ZWedge, qImage_cw_Box, qImage_cw_BoxImage, CenterOfMass ; PROCEDURE: ; state.img_wedge is checked to find out if the last call to ; qImage_cw_Update plotted a valid widget, instead of a square box. ; If it did then qImage_cw_ZWedge is called to calculate Z-values ; for the wedge. If not then Z-values are calculate using ; IDL function min, max, mean, and stddev (with the /nan keyword set). ; STATE INFO USED: ; widget_control, state.wid_smei, get_uvalue=smei_set ; widget_control, state.wid_center[0], get_value=x ; widget_control, state.wid_center[1], get_value=y ; STATE INFO MODIFIED: ; widget_control, state.wid_xyz[i+4], set_value=zval[i], i=0,3 ; widget_control, state.wid_phi[3], set_value=centroid[0]*!radeg ; widget_control, state.wid_rad[3], set_value=centroid[1] ; MODIFICATION HISTORY: ; FEB-2000, Paul Hick (UCSD/CASS) ; NOV-2005, Paul Hick (UCSD/CASS; pphick@ucsd.edu) ; Fixed bug in calculating standard deviation (make sure there ; are at least two good values to work with). ;- dp = 3 zval = replicate( BadValue(1.0 ), 4) centroid = replicate( BadValue(1.0d0), 2) zpix = 0 zpixback = 0 zback = BadValue(1.0) qImage_cw_Box, state, box, /get, p_box=p_box one_pixel = box[2] EQ box[0] AND box[3] EQ box[1] widget_control, state.wid_smei , get_uvalue=smei_set widget_control, state.wid_tool, get_uvalue=tool_state, /no_copy ellipse_set = tool_state.send.ellipse widget_control, state.wid_tool, set_uvalue=tool_state, /no_copy IF smei_set AND NOT one_pixel THEN BEGIN ; A dp-pixel wide strip along the outside of p_box is used to calculate a background ; to be used for the centroid calculation drad = dp+1. dphi = 2.*(dp+1)/(p_box[1]+p_box[3]) phi_e = p_box[2]+(2*!pi)*fix(p_box[2] LT p_box[0]) ; Set up box including background area surrounding p_box (outside p_box) ; Calculate the background in the dp-pixel wide strip zpixback = qImage_cw_ZWedge(state, p_box+[dphi,drad]#[-1,1], exclude_p_box=p_box, zval=zback, /noupdate) ; Add the background in the dp-pixel wide strip to the existing background CASE zpixback GT 0 OF 0: zpix = qImage_cw_ZWedge(state, p_box, zval=zval, /noupdate) 1: BEGIN zback = zback[2] ;widget_control, state.wid_background, get_value=background ;widget_control, state.wid_background, set_value=background+zback widget_control, state.wid_background, set_uvalue=zback zpix = qImage_cw_ZWedge(state, p_box, zval=zval, /noupdate, centroid=centroid) ;widget_control, state.wid_background, set_value=background widget_control, state.wid_background, set_uvalue=0 IF zpix GT 0 THEN BEGIN zval[0:2] = zval[0:2]+zback centroid = state.img_offset+centroid ENDIF END ENDCASE ;ENDIF ELSE IF ellipse_set AND NOT one_pixel THEN BEGIN ENDIF ELSE IF qImage_cw_BoxImage(state, box, sub_img=sub_img, sub_box=sub_box) THEN BEGIN zpix = total(finite(sub_img)) ; # finite values in sub_img zmax = max(sub_img, min=zmin, /nan) zavg = mean(sub_img, /nan) ; stddev crashes if there are less than 2 good values IF zpix GT 1 THEN zstd = stddev(sub_img, /nan) ELSE zstd = 0.0 zval = [zmin, zmax, zavg, zstd] ; Add dp pixel around box to calculate background. ; Could make box bigger than whole image, but that's ok tmp = qImage_cw_BoxImage(state, box+[dp,dp]#[-1,1], sub_img=sub_img_q, sub_box=sub_box_q) zpixback = total(finite(sub_img_q))-zpix IF zpixback GT 0 THEN BEGIN ; No background pixels available sub_box_q = sub_box-sub_box_q[0:1]#[1,1] sub_img_q[sub_box_q[0]:sub_box_q[2],sub_box_q[1]:sub_box_q[3]] = BadValue(sub_img_q) zback = mean(sub_img_q, /nan) centroid = state.img_offset+box[0:1]+CenterOfMass(sub_img-zback) ENDIF ENDIF ; The centroid is calculated in double precision, but the widget fields are only single ; precision, I think. To be on the safe side the double precision centroid is stored ; as user value to state.wid_xyz[8]. widget_control, state.wid_xyz[8], set_value=centroid[0], set_uvalue=centroid widget_control, state.wid_xyz[9], set_value=centroid[1], set_uvalue=float([zback,zpix,zpixback]) ; Update Z-min, Z-max, Z-avg, Z-std FOR i=0,3 DO widget_control, state.wid_xyz[4+i], set_value=zval[i] ; If the smei widget is active we also want to update the centroid ; in polar coordinates IF smei_set THEN BEGIN widget_control, state.wid_center[0], get_value=x widget_control, state.wid_center[1], get_value=y centroid = cv_coord(from_rect=centroid-([x,y]-state.img_offset), /to_polar) widget_control, state.wid_phi[3], set_value=centroid[0]*!radeg widget_control, state.wid_rad[3], set_value=centroid[1] ENDIF RETURN & END