;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; pc_seed_points.pro ;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; $Id$ ;;; ;;; Description: ;;; GUI for selecting a seed points within given coordinates. ;;; The returned array contains a list of seed points. ;;; Optional parameters are: ;;; * start (the starting coordinate, default: whole range) ;;; * description (description text for the list of seed points) ;;; * precision (the sub-grid precision for the tracing, default: 0.2) ;;; * select (select only every select-th point for extraction, default: 5) ;;; ;;; Example: ;;; IDL> seeds = pc_seed_points (grid) ;;; IDL> seeds = pc_seed_points (grid, start=[ px, py, pz ]) ;;; ; Update seed points dialog window pro pc_seed_points_update common seed_points_gui_common, sub_xs, sub_xe, sub_nx, sub_ys, sub_ye, sub_ny, sub_zs, sub_ze, sub_nz, sel_dx, sel_dy, sel_dz, num, descr, preci, selec common seed_points_common, coord, center, xs, xe, ys, ye, zs, ze, nx, ny, nz, num_x, num_y, num_z, dist_x, dist_y, dist_z, description_str, precision_float, select_int if ((dist_x eq 0) and (nx gt 1L)) then begin divisors = lindgen (xe - xs + 1L) + 1L divisors = divisors[where (((xe - xs + 1L) mod divisors) eq 0)] nx = divisors[pc_find_index (double (nx < max (divisors)), divisors, /round)] end if ((dist_y eq 0) and (ny gt 1L)) then begin divisors = lindgen (ye - ys + 1L) + 1L divisors = divisors[where (((ye - ys + 1L) mod divisors) eq 0)] ny = divisors[pc_find_index (double (ny < max (divisors)), divisors, /round)] end if ((dist_z eq 0) and (nz gt 1L)) then begin divisors = lindgen (ze - zs + 1L) + 1L divisors = divisors[where (((ze - zs + 1L) mod divisors) eq 0)] nz = divisors[pc_find_index (double (nz < max (divisors)), divisors, /round)] end WIDGET_CONTROL, sub_xs, SET_VALUE = xs + coord.x_off WIDGET_CONTROL, sub_xe, SET_VALUE = xe + coord.x_off WIDGET_CONTROL, sub_ys, SET_VALUE = ys + coord.y_off WIDGET_CONTROL, sub_ye, SET_VALUE = ye + coord.y_off WIDGET_CONTROL, sub_zs, SET_VALUE = zs + coord.z_off WIDGET_CONTROL, sub_ze, SET_VALUE = ze + coord.z_off WIDGET_CONTROL, sub_nx, SET_VALUE = nx WIDGET_CONTROL, sub_ny, SET_VALUE = ny WIDGET_CONTROL, sub_nz, SET_VALUE = nz WIDGET_CONTROL, num, SET_VALUE = nx*ny*nz end ; Event handling of seed points dialog window pro seed_points_event, event common seed_points_gui_common, sub_xs, sub_xe, sub_nx, sub_ys, sub_ye, sub_ny, sub_zs, sub_ze, sub_nz, sel_dx, sel_dy, sel_dz, num, descr, preci, selec common seed_points_common, coord, center, xs, xe, ys, ye, zs, ze, nx, ny, nz, num_x, num_y, num_z, dist_x, dist_y, dist_z, description_str, precision_float, select_int WIDGET_CONTROL, WIDGET_INFO (event.top, /CHILD) WIDGET_CONTROL, event.id, GET_UVALUE = eventval quit = -1 SWITCH eventval of 'RESET': begin xs = center[0] ys = center[0] zs = center[0] xe = xs ye = ys ze = zs nx = 1L ny = 1L nz = 1L break end 'SUB_XS': begin WIDGET_CONTROL, event.id, GET_VALUE = xs xs = ((xs - coord.x_off) > 0L) < (num_x-1L) xe = xe > xs break end 'SUB_YS': begin WIDGET_CONTROL, event.id, GET_VALUE = ys ys = ((ys - coord.y_off) > 0L) < (num_y-1L) ye = ye > ys break end 'SUB_ZS': begin WIDGET_CONTROL, event.id, GET_VALUE = zs zs = ((zs - coord.z_off) > 0L) < (num_z-1L) ze = ze > zs break end 'SUB_XE': begin WIDGET_CONTROL, event.id, GET_VALUE = xe xe = ((xe - coord.x_off) > 0L) < (num_x-1L) xs = xs < xe break end 'SUB_YE': begin WIDGET_CONTROL, event.id, GET_VALUE = ye ye = ((ye - coord.y_off) > 0L) < (num_y-1L) ys = ys < ye break end 'SUB_ZE': begin WIDGET_CONTROL, event.id, GET_VALUE = ze ze = ((ze - coord.z_off) > 0L) < (num_z-1L) zs = zs < ze break end 'SUB_NX': begin WIDGET_CONTROL, event.id, GET_VALUE = nx nx = nx > 1L break end 'SUB_NY': begin WIDGET_CONTROL, event.id, GET_VALUE = ny ny = ny > 1L break end 'SUB_NZ': begin WIDGET_CONTROL, event.id, GET_VALUE = nz nz = nz > 1L break end 'ALL_X': begin xs = 0L xe = num_x - 1L nx = xe - xs + 1L break end 'ALL_Y': begin ys = 0L ye = num_y - 1L ny = ye - ys + 1L break end 'ALL_Z': begin zs = 0L ze = num_z - 1L nz = ze - zs + 1L break end 'SEL_DX': begin dist_x = event.index break end 'SEL_DY': begin dist_y = event.index break end 'SEL_DZ': begin dist_z = event.index break end 'OK': begin WIDGET_CONTROL, descr, GET_VALUE = description_str WIDGET_CONTROL, preci, GET_VALUE = precision_float WIDGET_CONTROL, selec, GET_VALUE = select_int quit = event.top break end 'CANCEL': begin nx = 0L ny = 0L nz = 0L quit = event.top break end endswitch pc_seed_points_update WIDGET_CONTROL, WIDGET_INFO (event.top, /CHILD) if (quit ge 0) then WIDGET_CONTROL, quit, /DESTROY return end ; File selection dialog GUI. function pc_seed_points, grid, start=start, description=description, precision=precision, select=select common seed_points_gui_common, sub_xs, sub_xe, sub_nx, sub_ys, sub_ye, sub_ny, sub_zs, sub_ze, sub_nz, sel_dx, sel_dy, sel_dz, num, descr, preci, selec common seed_points_common, coord, center, xs, xe, ys, ye, zs, ze, nx, ny, nz, num_x, num_y, num_z, dist_x, dist_y, dist_z, description_str, precision_float, select_int ; Default settings: default, description, "pc_seed_points" default, precision, 0.2 default, select, 5 description_str = description precision_float = precision select_int = select coord = grid if (not has_tag (coord, 'x_off')) then coord = create_struct (coord, 'x_off', 0) if (not has_tag (coord, 'y_off')) then coord = create_struct (coord, 'y_off', 0) if (not has_tag (coord, 'z_off')) then coord = create_struct (coord, 'z_off', 0) num_x = n_elements (coord.x) num_y = n_elements (coord.y) num_z = n_elements (coord.z) xs = 0L xe = num_x - 1L ys = 0L ye = num_y - 1L zs = 0L ze = num_z - 1L if (keyword_set (start)) then begin xs = (round (start[0]) > xs) < xe ys = (round (start[1]) > ys) < ye zs = (round (start[2]) > zs) < ze xe = xs ye = ys ze = zs end center = [ xs, ys, zs ] nx = xe - xs + 1L ny = ye - ys + 1L nz = ze - zs + 1L ; Build GUI MOTHER = WIDGET_BASE (title='PC seed points selector', EVENT_PRO=seed_points_event) BASE = WIDGET_BASE (MOTHER, /row) CTRL = WIDGET_BASE (BASE, /col) dist_names = [ 'exact grid points', 'equidistant distribution', 'random distribution' ] dist_x = 0 dist_y = 0 dist_z = 0 tmp = WIDGET_LABEL (CTRL, value='Seed Point Selection (start, end, number):', frame=0) SEL = WIDGET_BASE (CTRL, frame=1, /align_center, /col) SUB = WIDGET_BASE (SEL, frame=0, /align_center, /row) sub_xs = CW_FIELD (SUB, title='X:', uvalue='SUB_XS', value=(xs + coord.x_off), /long, /return_events, xsize=5) tmp = WIDGET_BUTTON (SUB, xsize=100, value='<= MIN MAX =>', uvalue='ALL_X') sub_xe = CW_FIELD (SUB, title='', uvalue='SUB_XE', value=(xe + coord.x_off), /long, /return_events, xsize=5) sel_dx = WIDGET_DROPLIST (SUB, value=dist_names, uvalue='SEL_DX') sub_nx = CW_FIELD (SUB, title='=', uvalue='SUB_NX', value=nx, /long, /return_events, xsize=5) tmp = WIDGET_LABEL (SUB, value='seed points', frame=0) SUB = WIDGET_BASE (SEL, frame=0, /align_center, /row) sub_ys = CW_FIELD (SUB, title='Y:', uvalue='SUB_YS', value=(ys + coord.y_off), /long, /return_events, xsize=5) tmp = WIDGET_BUTTON (SUB, xsize=100, value='<= MIN MAX =>', uvalue='ALL_Y') sub_ye = CW_FIELD (SUB, title='', uvalue='SUB_YE', value=(ye + coord.y_off), /long, /return_events, xsize=5) sel_dy = WIDGET_DROPLIST (SUB, value=dist_names, uvalue='SEL_DY') sub_ny = CW_FIELD (SUB, title='=', uvalue='SUB_NY', value=ny, /long, /return_events, xsize=5) tmp = WIDGET_LABEL (SUB, value='seed points', frame=0) SUB = WIDGET_BASE (SEL, frame=0, /align_center, /row) sub_zs = CW_FIELD (SUB, title='Z:', uvalue='SUB_ZS', value=(zs + coord.z_off), /long, /return_events, xsize=5) tmp = WIDGET_BUTTON (SUB, xsize=100, value='<= MIN MAX =>', uvalue='ALL_Z') sub_ze = CW_FIELD (SUB, title='', uvalue='SUB_ZE', value=(ze + coord.z_off), /long, /return_events, xsize=5) sel_dz = WIDGET_DROPLIST (SUB, value=dist_names, uvalue='SEL_DZ') sub_nz = CW_FIELD (SUB, title='=', uvalue='SUB_NZ', value=nz, /long, /return_events, xsize=5) tmp = WIDGET_LABEL (SUB, value='seed points', frame=0) WIDGET_CONTROL, sub_xs, SENSITIVE = (num_x gt 1L) WIDGET_CONTROL, sub_xe, SENSITIVE = (num_x gt 1L) WIDGET_CONTROL, sub_nx, SENSITIVE = (num_x gt 1L) WIDGET_CONTROL, sub_ys, SENSITIVE = (num_y gt 1L) WIDGET_CONTROL, sub_ye, SENSITIVE = (num_y gt 1L) WIDGET_CONTROL, sub_ny, SENSITIVE = (num_y gt 1L) WIDGET_CONTROL, sub_zs, SENSITIVE = (num_z gt 1L) WIDGET_CONTROL, sub_ze, SENSITIVE = (num_z gt 1L) WIDGET_CONTROL, sub_nz, SENSITIVE = (num_z gt 1L) tmp = WIDGET_BASE (CTRL, frame=0, /align_center, /col) BUT = WIDGET_BASE (tmp, frame=0, /align_center, /row) descr = CW_FIELD (BUT, title='Description:', xsize=40) BUT = WIDGET_BASE (tmp, frame=0, /align_center, /row) preci = CW_FIELD (BUT, title='Precision:', /floating, xsize=10) selec = CW_FIELD (BUT, title='Select every:', /long, xsize=10) WIDGET_CONTROL, descr, SET_VALUE = description_str WIDGET_CONTROL, preci, SET_VALUE = precision_float WIDGET_CONTROL, selec, SET_VALUE = select_int BUT = WIDGET_BASE (CTRL, frame=0, /align_center, /row) num = CW_FIELD (BUT, title='Number of Streamlines:', /long, /noedit, xsize=10) WIDGET_CONTROL, num, SET_VALUE = nx*ny*nz SUB = WIDGET_BASE (BUT, frame=0, /align_center, /row) tmp = WIDGET_BUTTON (SUB, xsize=80, value='RESET', uvalue='RESET') GRP = WIDGET_BASE (BUT, frame=1, /align_center, /row) tmp = WIDGET_BUTTON (GRP, xsize=80, value='CANCEL', uvalue='CANCEL') tmp = WIDGET_BUTTON (GRP, xsize=80, value='OK', uvalue='OK') WIDGET_CONTROL, MOTHER, /REALIZE wimg = !d.window WIDGET_CONTROL, BASE XMANAGER, "seed_points", MOTHER ; Check for abortion or impossible values if (nx * ny * nz le 0L) then return, -1L ; Build list of selected seed points if (dist_x eq 2) then rx = 1 else rx = 0 if (dist_y eq 2) then ry = 1 else ry = 0 if (dist_z eq 2) then rz = 1 else rz = 0 x_start = coord.x[xs] - rx * 0.5 * coord.dx[xs] y_start = coord.y[ys] - ry * 0.5 * coord.dy[ys] z_start = coord.z[zs] - rz * 0.5 * coord.dz[zs] x_end = coord.x[xe] + rx * 0.5 * coord.dx[xe] y_end = coord.y[ye] + ry * 0.5 * coord.dy[ye] z_end = coord.z[ze] + rz * 0.5 * coord.dz[ze] if (grid.lperi[0]) then x_start = x_start > coord.x[0] & x_end = x_end < coord.x[num_x-1] if (grid.lperi[1]) then y_start = y_start > coord.y[0] & y_end = y_end < coord.y[num_y-1] if (grid.lperi[2]) then z_start = z_start > coord.z[0] & z_end = z_end < coord.z[num_z-1] dx = x_end - x_start dy = y_end - y_start dz = z_end - z_start seeds = dblarr (3, nx * ny * nz) seed = long (systime (/seconds)) pos = 0L if ((dist_x eq 0) and (num_x ne nx)) then step_x = (xe - xs + 1L) / nx else step_x = 1L if ((dist_y eq 0) and (num_y ne ny)) then step_y = (ye - ys + 1L) / ny else step_y = 1L if ((dist_z eq 0) and (num_z ne nz)) then step_z = (ze - zs + 1L) / nz else step_z = 1L for pos_z = 0L, nz - 1L do begin for pos_y = 0L, ny - 1L do begin for pos_x = 0L, nx - 1L do begin if (rx ne 0) then px = randomu (seed, /double) else if (nx le 1L) then px = pos_x / (nx - 1.0d0) else px = 0.5d0 if (ry ne 0) then py = randomu (seed, /double) else if (ny le 1L) then py = pos_y / (ny - 1.0d0) else py = 0.5d0 if (rz ne 0) then pz = randomu (seed, /double) else if (nz le 1L) then pz = pos_z / (nz - 1.0d0) else pz = 0.5d0 if (dist_x eq 0) then x = coord.x[xs + pos_x * step_x] else x = x_start + px * dx if (dist_y eq 0) then y = coord.y[ys + pos_y * step_y] else y = y_start + py * dy if (dist_z eq 0) then z = coord.z[zs + pos_z * step_z] else z = z_start + pz * dz seeds[*,pos] = [ x, y, z ] pos += 1L end end end description = description_str if (size (description, /n_dimensions) eq 1) then description = description[0] precision = precision_float select = select_int return, reform (seeds) end