def trim_array_to_ROI(img, return_support_region=False): """Crop an image to the boundaries specified by the circumscribed rectangle of the region defined by a mask. :param 2d numpy masked array img: mask is the region of interest. :param bool return_support_region: If set to true, also the boudaries of the circumscribed rectangle are returned. Default is False. :returns: 2d numpy array, cropped image :returns: If *return_support_region* is set, also a list with coordinates of the ROI circumscribed rectangle is returned. """ #img.mask = np.logical_not(img.mask) edges_y = [] for row in img: edges = ma.notmasked_edges(row) if edges is not None: edges_y.append(edges) edges_x = [] for col in np.swapaxes(img, 0, 1): edges = ma.notmasked_edges(col) if edges is not None: edges_x.append(edges) if edges_x == [] and edges_y == []: return None edges_x = np.swapaxes(edges_x, 0, 1) edges_y = np.swapaxes(edges_y, 0, 1) min_x = np.min(edges_x[0]) max_x = np.max(edges_x[1]) min_y = np.min(edges_y[0]) max_y = np.max(edges_y[1]) # do not return stripes if max_x - min_x <= 1: if min_x == 0: max_x += 1 elif max_x == edges_x[1, -1]: min_x -= 1 else: max_x += 1 if max_y - min_y <= 1: if min_y == 0: max_x += 1 elif max_y == edges_y[1, -1]: min_y -= 1 else: max_y += 1 new_data = img.data[min_x:max_x + 1, min_y:max_y + 1] support_region = [(min_x, max_x + 1), (min_y, max_y + 1)] if return_support_region: return new_data, support_region return new_data
def _jprimes(x, i, x_bounds=None): """ Helper function to return the j' indices for the master curve fit This function is a helper function for :py:func:`quality`. It is not supposed to be called directly. Parameters ---------- x : mapping to ndarrays The x values. i : int The row index (finite size index) x_bounds : 2-tuple, optional bounds on x values Returns ------- ret : mapping to ndarrays Has the same keys and shape as `x`. Its element ``ret[i'][j]`` is the j' such that :math:`x_{i'j'} \leq x_{ij} < x_{i'(j'+1)}`. If no such j' exists, the element is np.nan. Convert the element to int to use as an index. """ j_primes = -np.ones_like(x) try: x_masked = ma.masked_outside(x, x_bounds[0], x_bounds[1]) except (TypeError, IndexError): x_masked = ma.asanyarray(x) k, n = x.shape # indices of lower and upper bounds edges = ma.notmasked_edges(x_masked, axis=1) x_lower = np.zeros(k, dtype=int) x_upper = np.zeros(k, dtype=int) x_lower[edges[0][0]] = edges[0][-1] x_upper[edges[-1][0]] = edges[-1][-1] for i_prime in range(k): if i_prime == i: j_primes[i_prime][:] = np.nan continue jprimes = np.searchsorted(x[i_prime], x[i], side='right').astype(float) - 1 jprimes[np.logical_or(jprimes < x_lower[i_prime], jprimes >= x_upper[i_prime])] = np.nan j_primes[i_prime][:] = jprimes return j_primes
def x_grad_u(RomsFile, RomsGrd, varname): """ compute x-gradient on u points """ if type(varname) == str: #load roms file RomsNC = nc4(RomsFile, 'r') #load variable _var = RomsNC.variables[varname][:] else: _var = varname #[u points] #get mask Mask = ma.getmask(_var) #gradient in x direction [rho points] dvar_rho = ma.diff(_var, n=1, axis=3) #pad mask_pad = ma.notmasked_edges(dvar_rho, axis=3) dvar_ = dvar_rho dvar_[:, :, :, mask_pad[0][3][0] - 1] = dvar_rho[:, :, :, mask_pad[0][3][0]] dvar_[:, :, :, mask_pad[1][3][0] + 1] = dvar_rho[:, :, :, mask_pad[1][3][0]] dvar_pad = ma.concatenate((dvar_rho[:,:,:,0:1], dvar_rho, \ dvar_rho[:,:,:,-2:-1]), axis = 3) #shift to u points dvar_u = GridShift.Rho_to_Upt(dvar_pad) #dx [rho points] x_dist = rt.rho_dist_grd(RomsGrd)[0] #repeat over depth and time and apply mask _dx = rt.AddDepthTime(RomsFile, x_dist) dx = ma.array(GridShift.Rho_to_Upt(_dx), mask=Mask) #gradient dvar_dx = dvar_u / dx return dvar_dx
def y_grad_v(RomsFile, RomsGrd, varname): """ Compute y-gradient on v points """ if type(varname) == str: #load roms file RomsNC = nc4(RomsFile, 'r') #load variable _var = RomsNC.variables[varname][:] else: _var = varname #[v points] #get mask Mask = ma.getmask(_var) #compute difference [rho points] dvar_rho = ma.diff(_var, n=1, axis=2) #pad mask_pad = ma.notmasked_edges(dvar_rho, axis=2) dvar_ = dvar_rho dvar_[:, :, mask_pad[0][2][0] - 1, :] = dvar_rho[:, :, mask_pad[0][2][0], :] dvar_[:, :, mask_pad[1][2][0] + 1, :] = dvar_rho[:, :, mask_pad[1][2][0], :] dvar_pad = ma.concatenate((dvar_[:,:,0:1, :],\ dvar_, \ dvar_[:,:,-2:-1, :]), axis = 2) #shift to V points dvar_v = GridShift.Rho_to_Vpt(dvar_pad) #dy y_dist = rt.rho_dist_grd(RomsGrd)[1] dy = rt.AddDepthTime(RomsFile, y_dist) dy_v = ma.array(GridShift.Rho_to_Vpt(dy), mask=Mask) #compute gradient dvar_dy = dvar_v / dy_v return dvar_dy
def rolling_measures_time(data, eye, units, win_size): """ Calculates rolling window measures @author: Raimondas Zemblys @email: [email protected] """ measures=dict() fs = data['eyetracker_sampling_rate'][0] win_size_sample = np.int16(win_size*fs)+1 #adjust window size to account for the uncertainty of a measurement win_size+=1.0/fs/2 #get masks for windows based on time temp_acc=np.diff(data['time']) rolling_temp_acc_for_data=np.cumsum(np.insert(rolling_window(temp_acc,win_size_sample*2-1), 0, np.zeros(len(temp_acc)-(win_size_sample-1)*2), axis=1), axis=1) rolling_temp_acc_for_isd=np.cumsum(rolling_window(temp_acc,win_size_sample*2-1), axis=1) mask_data=ma.getmaskarray(ma.masked_greater(rolling_temp_acc_for_data, win_size)) mask_isd=ma.getmaskarray(ma.masked_greater(rolling_temp_acc_for_isd, win_size)) #Data rolling_data_x = ma.array(rolling_window(data['_'.join((eye, units, 'x'))], win_size_sample*2),mask=mask_data) rolling_data_y = ma.array(rolling_window(data['_'.join((eye, units, 'y'))], win_size_sample*2),mask=mask_data) #Position error err_x = data['_'.join((eye, units, 'x'))] - data[stim_pos_mappings[units]+'x'] err_y = data['_'.join((eye, units, 'y'))] - data[stim_pos_mappings[units]+'y'] rolling_err_x = ma.array(rolling_window(err_x, win_size_sample*2),mask=mask_data) rolling_err_y = ma.array(rolling_window(err_y, win_size_sample*2),mask=mask_data) rolling_err_xy = ma.array(rolling_window(np.hypot(err_x, err_y), win_size_sample*2),mask=mask_data) #Time rolling_time = ma.array(rolling_window(data['time'], win_size_sample*2),mask=mask_data) measures['_'.join((eye, units, 'sample_count'))] = np.sum(mask_data, axis=1) notmasked_edges=ma.notmasked_edges(rolling_time, axis=1) start_times = ma.getdata(rolling_time[notmasked_edges[0][0],notmasked_edges[0][1]]) end_times = ma.getdata(rolling_time[notmasked_edges[1][0],notmasked_edges[1][1]]) measures['_'.join((eye, units, 'actual_win_size'))] = end_times-start_times ### RMS isd = np.diff([data['_'.join((eye, units, 'x'))], data['_'.join((eye, units, 'y'))]], axis=1).T rolling_isd_x = ma.array(rolling_window(isd[:,0], win_size_sample*2-1),mask=mask_isd) rolling_isd_y = ma.array(rolling_window(isd[:,1], win_size_sample*2-1),mask=mask_isd) RMS=[] for rms in [np.sqrt(np.mean(np.square(rolling_isd_x), 1)), np.sqrt(np.mean(np.square(rolling_isd_y), 1)), ]: rms_tmp = ma.getdata(rms) mask = ma.getmask(rms) rms_tmp[mask]=np.nan RMS.append(rms_tmp) measures['_'.join((eye, units, 'RMS', 'x'))] = RMS[0] measures['_'.join((eye, units, 'RMS', 'y'))] = RMS[1] measures['_'.join((eye, units, 'RMS'))] = np.hypot(RMS[0], RMS[1]) ### #RMS of PE isd = np.diff([err_x, err_y], axis=1).T rolling_isd_x = ma.array(rolling_window(isd[:,0], win_size_sample*2-1),mask=mask_isd) rolling_isd_y = ma.array(rolling_window(isd[:,1], win_size_sample*2-1),mask=mask_isd) RMS=[] for rms in [np.sqrt(np.mean(np.square(rolling_isd_x), 1)), np.sqrt(np.mean(np.square(rolling_isd_y), 1)), ]: rms_tmp = ma.getdata(rms) mask = ma.getmask(rms) rms_tmp[mask]=np.nan RMS.append(rms_tmp) measures['_'.join((eye, units, 'RMS_PE', 'x'))] = RMS[0] measures['_'.join((eye, units, 'RMS_PE', 'y'))] = RMS[1] measures['_'.join((eye, units, 'RMS_PE'))] = np.hypot(RMS[0], RMS[1]) ### ###STD STD=[] for std in [np.std(rolling_data_x, axis=1), np.std(rolling_data_y, axis=1)]: std_tmp = ma.getdata(std) mask = ma.getmask(std) std_tmp[mask]=np.nan STD.append(std_tmp) measures['_'.join((eye, units, 'STD', 'x'))] = STD[0] measures['_'.join((eye, units, 'STD', 'y'))] = STD[1] measures['_'.join((eye, units, 'STD'))] = np.hypot(STD[0], STD[1]) #STD of PE STD=[] for std in [np.std(rolling_err_x, axis=1), np.std(rolling_err_y, axis=1)]: std_tmp = ma.getdata(std) mask = ma.getmask(std) std_tmp[mask]=np.nan STD.append(std_tmp) measures['_'.join((eye, units, 'STD_PE', 'x'))] = STD[0] measures['_'.join((eye, units, 'STD_PE', 'y'))] = STD[1] measures['_'.join((eye, units, 'STD_PE'))] = np.hypot(STD[0], STD[1]) ###ACC ACC=[] for acc in [np.median(rolling_err_x, axis=1), np.median(rolling_err_y, axis=1)]: acc_tmp = ma.getdata(acc) mask = ma.getmask(acc) acc_tmp[mask]=np.nan ACC.append(acc_tmp) measures['_'.join((eye, units, 'ACC', 'x'))] = ACC[0] measures['_'.join((eye, units, 'ACC', 'y'))] = ACC[1] measures['_'.join((eye, units, 'ACC'))] = np.hypot(ACC[0], ACC[1]) #Absolute accuracy ACC=[] for acc in [np.median(np.abs(rolling_err_x), axis=1), np.median(np.abs(rolling_err_y), axis=1), np.median(rolling_err_xy, axis=1)]: acc_tmp = ma.getdata(acc) mask = ma.getmask(acc) acc_tmp[mask]=np.nan ACC.append(acc_tmp) measures['_'.join((eye, units, 'ACC_abs', 'x'))] = ACC[0] measures['_'.join((eye, units, 'ACC_abs', 'y'))] = ACC[1] measures['_'.join((eye, units, 'ACC_abs'))] = ACC[2] #Fix FIX=[] for fix in [np.median(rolling_data_x, axis=1), np.median(rolling_data_y, axis=1)]: fix_tmp = ma.getdata(fix) mask = ma.getmask(fix) fix_tmp[mask]=np.nan FIX.append(fix_tmp) measures['_'.join((eye, units, 'fix', 'x'))] = FIX[0] measures['_'.join((eye, units, 'fix', 'y'))] = FIX[1] ### return measures
def _jprimes(x, i, x_bounds=None): """ Helper function to return the j' indices for the master curve fit This function is a helper function for :py:func:`quality`. It is not supposed to be called directly. Parameters ---------- x : mapping to ndarrays The x values. i : int The row index (finite size index) x_bounds : 2-tuple, optional bounds on x values Returns ------- ret : mapping to ndarrays Has the same keys and shape as `x`. Its element ``ret[i'][j]`` is the j' such that :math:`x_{i'j'} \leq x_{ij} < x_{i'(j'+1)}`. If no such j' exists, the element is np.nan. Convert the element to int to use as an index. """ j_primes = - np.ones_like(x) try: x_masked = ma.masked_outside(x, x_bounds[0], x_bounds[1]) except (TypeError, IndexError): x_masked = ma.asanyarray(x) k, n = x.shape # indices of lower and upper bounds edges = ma.notmasked_edges(x_masked, axis=1) x_lower = np.zeros(k, dtype=int) x_upper = np.zeros(k, dtype=int) x_lower[edges[0][0]] = edges[0][-1] x_upper[edges[-1][0]] = edges[-1][-1] for i_prime in range(k): if i_prime == i: j_primes[i_prime][:] = np.nan continue jprimes = np.searchsorted( x[i_prime], x[i], side='right' ).astype(float) - 1 jprimes[ np.logical_or( jprimes < x_lower[i_prime], jprimes >= x_upper[i_prime] ) ] = np.nan j_primes[i_prime][:] = jprimes return j_primes