pro contract_arrays, full_array, ptr_array, fill, n_ptr_dims=n_ptr_dims ; given an array and a fill value, make a new array of pointers to ; arrays that contains the arrays with "empty" space that contained ; the fill value removed and each array made smaller as needed ; (assume the last dimension is the # of arrays dimension) ; note: if fill isn't provided, don't contract, just make into pointers ; also note: if new_ptr_array is already an array of (null) pointers, ; fill it directly instead of divining the dimensions for it. ; If ptr_array isn't set, but n_ptr_dims is provided, ptr_array will take that ; number of dimensions from the end of the full_array dims for its size. dont_contract = 0 if (n_params() lt 3) then begin ; didn't get a fill value fill = 0 dont_contract = 1 endif dims = size(full_array, /dimensions) if dims[0] eq 0 then begin ; full_array shouldn't be scalar, but oh well dims = [1] endif n_dims = n_elements(dims) if (size(ptr_array, /type) eq 10) then begin n_ptr_dims = size(ptr_array, /n_dimensions) n_ptrs = n_elements(ptr_array) ptr_dims = size(ptr_array, /dim) n_tmp_dims = n_dims - 1 n_elem = 1 while (n_tmp_dims ge 0) and (n_elem lt n_ptrs) do begin n_elem = n_elem * dims[n_tmp_dims] n_tmp_dims = n_tmp_dims - 1 endwhile if (n_elem ne n_ptrs) then begin print, 'ERROR: full_array does not compact neatly into ptr_array' return endif n_tmp_dims = n_tmp_dims + 1 tmp_ptr_array = 0 n_ptr_dims = n_dims-n_tmp_dims if (n_ptr_dims gt 0) then $ ptr_dims = dims[n_tmp_dims:n_dims-1] $ else $ ptr_dims = 1 endif else begin if size(n_ptr_dims, /type) ne 0 then begin n_ptr_dims = long(n_ptr_dims) n_tmp_dims = (n_dims - n_ptr_dims) > 0 if (n_ptr_dims gt n_dims) then $ ptr_dims = [ lonarr(n_ptr_dims-n_dims) + 1, dims ] $ else if (n_ptr_dims gt 0) then $ ptr_dims = dims[n_tmp_dims:n_dims-1] $ else $ ptr_dims = 1 endif else begin ; by default, use just the last dimension ; for the pointers n_tmp_dims = n_dims - 1 n_ptr_dims = 1 ptr_dims = [ dims[n_tmp_dims] ] endelse ptr_array = make_array(dim=ptr_dims, type=10) n_ptrs = n_elements(ptr_array) endelse atype = size(full_array, /type) fval = fix(fill, type=atype, /print) n_ptr_dims = n_elements(ptr_dims) if (n_tmp_dims eq 0) then begin for j=0L,n_ptrs-1 do begin tmp = full_array[j] if (dont_contract) or (tmp[0] ne fval) then $ ptr_array[j] = ptr_new(tmp) $ else $ ptr_array[j] = ptr_new() endfor endif else if (n_ptrs eq 1) then begin tmp = full_array if (not dont_contract) then begin switch n_tmp_dims of 7: shorten_array, tmp, 7, fval 6: shorten_array, tmp, 6, fval 5: shorten_array, tmp, 5, fval 4: shorten_array, tmp, 4, fval 3: shorten_array, tmp, 3, fval 2: shorten_array, tmp, 2, fval 1: shorten_array, tmp, 1, fval endswitch endif if (dont_contract) or (size(tmp, /n_dimensions) gt 0) $ or (tmp[0] ne fval) then $ ptr_array[0] = ptr_new(tmp) $ else $ ptr_array[0] = ptr_new() endif else begin if n_ptr_dims gt 1 then begin n_dims = n_tmp_dims + 1 full_array = reform(full_array, [ dims[0:n_tmp_dims-1], n_ptrs ], /overwrite) endif for j=0L,n_ptrs-1 do begin tmp = 0 case n_dims of 1: tmp = full_array[j] 2: tmp = full_array[*,j] 3: tmp = full_array[*,*,j] 4: tmp = full_array[*,*,*,j] 5: tmp = full_array[*,*,*,*,j] 6: tmp = full_array[*,*,*,*,*,j] 7: tmp = full_array[*,*,*,*,*,*,j] 8: tmp = full_array[*,*,*,*,*,*,*,j] endcase if (dont_contract eq 0) then begin switch n_tmp_dims of 7: shorten_array, tmp, 7, fval 6: shorten_array, tmp, 6, fval 5: shorten_array, tmp, 5, fval 4: shorten_array, tmp, 4, fval 3: shorten_array, tmp, 3, fval 2: shorten_array, tmp, 2, fval 1: shorten_array, tmp, 1, fval endswitch endif if (dont_contract) or (size(tmp, /n_dimensions) gt 0) $ or (tmp[0] ne fval) then $ ptr_array[j] = ptr_new(tmp) $ else $ ptr_array[j] = ptr_new() tmp = 0 endfor if n_ptr_dims gt 1 then begin ; put full_array back the way it was full_array = reform(full_array, dims, /overwrite) endif endelse end