def process_s(s): s.values[s.values == 0] = np.nan s.values[np.logical_or(np.isinf(s.values), np.isnan(s.values))] = np.nan s, had_outlier = _setnull_s_outliers(s) while had_outlier: s, had_outlier = _setnull_s_outliers(s) has_null = s.isnull().any() if has_null: try: r, c = np.nonzero(np.isfinite(s.values)) y = s.lat[r].values x = s.lon[c].values points = (x, y) values = s.values[r, c] grid_x, grid_y = np.meshgrid(s.lon.values, s.lat.values) try: sgrid = griddata(points, values, (grid_x, grid_y), method='cubic') except QhullError: sgrid = np.zeros(s.shape) try: sgrid_l = griddata(points, values, (grid_x, grid_y), method='linear') except QhullError: sgrid_l = np.empty(s.shape) sgrid_l.fill(np.nan) sgrid_n = griddata(points, values, (grid_x, grid_y), method='nearest') mask_zero = sgrid <= 0 sgrid[mask_zero] = sgrid_l[mask_zero] mask_nan = np.isnan(sgrid) sgrid[mask_nan] = sgrid_n[mask_nan] s = xr.DataArray(sgrid, coords=[s.lat, s.lon]) except ValueError as e: if e.args[0] == 'No points given': # No valid scaler factors s.values[:] = 1 else: raise return s
def inv_dense_corres(dense_corres_a2b, pre_cache_x2d=None): H, W = dense_corres_a2b.shape[:2] if pre_cache_x2d is None: x_a = x_2d_coords(H, W).reshape((H, W, 2)) else: x_a = pre_cache_x2d.reshape((H, W, 2)) dense_corres_b2a = griddata(dense_corres_a2b.reshape((H * W, 2)), x_a.reshape((H * W, 2)), x_a.reshape((H * W, 2)), method='linear', fill_value=-1) return dense_corres_b2a.reshape((H, W, 2))
def _extract_h5(self, dm): # cells = [] tab = dm.get_table('power_map', '/') metadata = dict() try: b = tab._v_attrs['bounds'] except Exception as e: print('exception', e) b = 1 metadata['bounds'] = -float(b), float(b) try: bd = tab._v_attrs['beam_diameter'] except Exception as e: print('exception', e) bd = 0 try: po = tab._v_attrs['power'] except Exception as e: print('exception', e) po = 0 metadata['beam_diameter'] = bd metadata['power'] = po xs, ys, power = array([(r['x'], r['y'], r['power']) for r in tab.iterrows()]).T # xs, ys, power = array(xs), array(ys), array(power) # n = power.shape[0] # print n xi = linspace(min(xs), max(xs), 50) yi = linspace(min(ys), max(ys), 50) X = xi[None, :] Y = yi[:, None] power = griddata( (xs, ys), power, (X, Y), fill_value=0, # method='cubic' ) return rot90(power, k=2), metadata
def _extract_h5(self, dm): # cells = [] tab = dm.get_table('power_map', '/') metadata = dict() try: b = tab._v_attrs['bounds'] except Exception as e: print('exception', e) b = 1 metadata['bounds'] = -float(b), float(b) try: bd = tab._v_attrs['beam_diameter'] except Exception as e: print('exception', e) bd = 0 try: po = tab._v_attrs['power'] except Exception as e: print('exception', e) po = 0 metadata['beam_diameter'] = bd metadata['power'] = po xs, ys, power = array([(r['x'], r['y'], r['power']) for r in tab.iterrows()]).T # xs, ys, power = array(xs), array(ys), array(power) # n = power.shape[0] # print n xi = linspace(min(xs), max(xs), 50) yi = linspace(min(ys), max(ys), 50) X = xi[None, :] Y = yi[:, None] power = griddata((xs, ys), power, (X, Y), fill_value=0, # method='cubic' ) return rot90(power, k=2), metadata
def _add_data(self, data): # def _refresh_data(v): tab, x, y, col, row, mag, sid = data # self.debug('{} {} {} {} {}'.format(*v[1:])) self._write_datum(tab, x, y, col, row, mag) self.graph.add_datum((x, mag), series=sid) self._xs = hstack((self._xs, x)) self._ys = hstack((self._ys, y)) self._zs = hstack((self._zs, mag)) # xl, xh = self._bounds[:2] # yl, yh = self._bounds[2:] if col % 10 == 0 and row: cg = self.contour_graph xx = self._xs yy = self._ys z = self._zs # print 'xx-----', xx # print 'yy-----', yy zd = griddata( (xx, yy), z, self.area, # method='cubic', fill_value=0) zd = rot90(zd, k=2) # zd = zd.T # print zd if not cg.plots[0].plots.keys(): cg.new_series( z=zd, xbounds=(-self._padding, self._padding), ybounds=(-self._padding, self._padding), # xbounds=(xl, xh), # ybounds=(yl, yh), style='contour') else: cg.plots[0].data.set_data('z0', zd)
def _add_data(self, data): # def _refresh_data(v): tab, x, y, col, row, mag, sid = data # self.debug('{} {} {} {} {}'.format(*v[1:])) self._write_datum(tab, x, y, col, row, mag) self.graph.add_datum((x, mag), series=sid) self._xs = hstack((self._xs, x)) self._ys = hstack((self._ys, y)) self._zs = hstack((self._zs, mag)) # xl, xh = self._bounds[:2] # yl, yh = self._bounds[2:] if col % 10 == 0 and row: cg = self.contour_graph xx = self._xs yy = self._ys z = self._zs # print 'xx-----', xx # print 'yy-----', yy zd = griddata((xx, yy), z, self.area, # method='cubic', fill_value=0) zd = rot90(zd, k=2) # zd = zd.T # print zd if not cg.plots[0].plots.keys(): cg.new_series(z=zd, xbounds=(-self._padding, self._padding), ybounds=(-self._padding, self._padding), # xbounds=(xl, xh), # ybounds=(yl, yh), style='contour') else: cg.plots[0].data.set_data('z0', zd)
def min(self, source_depths, receiver_depths, distances, method='linear'): ''' Returns the minimum (minima) travel time(s) for the point(s) identified by (source_depths, receiver_depths, distances) by building a grid and interpolating on the points identified by each ``` P[i] = (source_depths[i], receiver_depths[i], distances[i]) ``` if the source file has been built with receiver depths == [0]. It uses a 2d linear interpolation on a grid. It uses scipy griddata :param source_depths: numeric or numpy array of length n: the source depth(s), in km :param receiver_depths: numeric or numpy array of length n: the receiver depth(s), in km. For most applications, this value can be set to zero :param distances: numeric or numpy array of length n: the distance(s), in degrees :param method: forwarded to `scipy.griddata` function :return: a numpy array of length n denoting the minimum travel time(s) of this model for each P ''' # Handle the case some arguments are scalars and some arrays: source_depths, receiver_depths, distances = \ np.broadcast_arrays(source_depths, receiver_depths, distances) # handle the case all arguments scalars. See # https://stackoverflow.com/questions/29318459/python-function-that-handles-scalar-or-arrays allscalars = all(_.ndim == 0 for _ in (source_depths, receiver_depths, distances)) if source_depths.ndim == 0: source_depths = source_depths[None] # Makes x 1D if receiver_depths.ndim == 0: receiver_depths = receiver_depths[None] # Makes x 1D if distances.ndim == 0: distances = distances[None] # Makes x 1D # correct source depths and receiver depths source_depths[source_depths < 0] = 0 receiver_depths[receiver_depths < 0] = 0 # correct distances to be compatible with obpsy traveltimes calculations: distances = distances % 360 # set values symmetric to 180 degrees if greater than 180: _mask = distances > 180 if _mask.any( ): # does this speeds up (allocate mask array once)? FIXME: check distances[_mask] = 360 - distances[_mask] # set source depths to nan if out of bounds. This prevent method = 'nearest' # to return non nan values and be consistent with 'linear' and 'cubic' if self._unique_receiver_depth: # get values without receiver depth dimension: values = np.hstack((self._km2deg(source_depths).reshape(-1, 1), distances.reshape(-1, 1))) else: values = np.hstack((self._km2deg(source_depths).reshape(-1, 1), self._km2deg(receiver_depths).reshape(-1, 1), distances.reshape(-1, 1))) ret = griddata(self._gridpts, self._gridvals, values, method=method, rescale=False, fill_value=np.nan) # ret is almost likely a float, so we can set now nans for out of boun values # we cannot do it before on any input array cause int arrays do not support nan assignement ret[(source_depths > self._sourcedepth_bounds_km[1]) | (receiver_depths > self._receiverdepth_bounds_km[1])] = np.nan # return scalar if inputs are scalar, array oitherwise return np.squeeze(ret) if allscalars else ret
# imports import nmafeat from prody import * import numpy as np # %% nmafeat.computeNMDfile() (coords, modes) = nmafeat.extractModesCoords() print(f"Values range from {coords.min()} to {coords.max()}") # %% dmin = coords.min() - 2 dmax = coords.max() + 2 a = np.mgrid[dmin:dmax:101j,dmin:dmax:101j,dmin:dmax:101j] a = a.reshape(3,1030301).transpose() # %% import scipy.interpolate.ndgriddata as ndgriddata mode1_interp = ndgriddata.griddata(coords, modes[0], a) # interpolate the data onto the grid # %% # Eureka! Maybe it worked!: # is not nan mode1_interp[~np.isnan(mode1_interp)].size # %% # is nan mode1_interp[np.isnan(mode1_interp)].size # %% δ = np.gradient(mode1_interp) # %% δ[0][~np.isnan(δ[0])].size # %% m1i_orig = mode1_interp.reshape(3,101,101,101) # %% m1i_grad = np.gradient(m1i_orig)
metadata['power'] = po xs, ys, power = array([(r['x'], r['y'], r['power']) for r in tab.iterrows()]).T # xs, ys, power = array(xs), array(ys), array(power) # n = power.shape[0] # print n xi = linspace(min(xs), max(xs), 50) yi = linspace(min(ys), max(ys), 50) X = xi[None, :] Y = yi[:, None] power = griddata((xs, ys), power, (X, Y), fill_value=0, # method='cubic' ) return rot90(power, k=2), metadata # return flipud(fliplr(power)), metadata # for row in tab.iterrows(): # x = int(row['col']) # try: # nr = cells[x] # except IndexError: # cells.append([]) # nr = cells[x] # # # baseline = self._calc_baseline(table, index) if self.correct_baseline else 0.0 # baseline = 0 # pwr = row['power']
def scale_anoms(s, obs_anoms): vals_d = obs_anoms.copy() mask_wet = vals_d.values > 0 vals_d.values[mask_wet] = vals_d.values[mask_wet] + s.values[mask_wet] mask_wet_invalid = np.logical_and(mask_wet, vals_d.values <= 0) has_invalid = mask_wet_invalid.any() try: if has_invalid: s.values[np.logical_or(mask_wet_invalid, ~mask_wet)] = np.nan r, c = np.nonzero(np.isfinite(s.values)) y = s.lat[r].values x = s.lon[c].values points = (x, y) values = s.values[r, c] grid_x, grid_y = np.meshgrid(s.lon.values, s.lat.values) try: sgrid = griddata(points, values, (grid_x, grid_y), method='cubic') except QhullError: sgrid = np.empty(s.shape) sgrid.fill(np.nan) sgrid_n = griddata(points, values, (grid_x, grid_y), method='nearest') mask_nan = np.isnan(sgrid) sgrid[mask_nan] = sgrid_n[mask_nan] s = xr.DataArray(sgrid, coords=[s.lat, s.lon]) vals_d = obs_anoms.copy() mask_wet = vals_d.values > 0 vals_d.values[ mask_wet] = vals_d.values[mask_wet] + s.values[mask_wet] mask_wet_invalid = np.logical_and(mask_wet, vals_d.values <= 0) has_invalid = mask_wet_invalid.any() if has_invalid: vals_d.values[mask_wet_invalid] = np.nan r, c = np.nonzero(vals_d.values > 0) y = vals_d.lat[r].values x = vals_d.lon[c].values points = (x, y) values = vals_d.values[r, c] grid_x, grid_y = np.meshgrid(vals_d.lon.values, vals_d.lat.values) try: vals_d_grid = griddata(points, values, (grid_x, grid_y), method='cubic') except QhullError: vals_d_grid = np.zeros(vals_d.shape) try: vals_d_grid_l = griddata(points, values, (grid_x, grid_y), method='linear') except QhullError: vals_d_grid_l = np.empty(vals_d.shape) vals_d_grid_l.fill(np.nan) vals_d_grid_n = griddata(points, values, (grid_x, grid_y), method='nearest') mask_zero = vals_d_grid <= 0 vals_d_grid[mask_zero] = vals_d_grid_l[mask_zero] mask_nan = np.isnan(vals_d_grid) vals_d_grid[mask_nan] = vals_d_grid_n[mask_nan] vals_d = xr.DataArray(vals_d_grid, coords=[vals_d.lat, vals_d.lon]) vals_d.values[obs_anoms.values == 0] = 0 except ValueError as e: if e.args[0] == 'No points given': # No valid scaler factors vals_d = obs_anoms.copy() else: raise return vals_d
def plot_images(self, figure, centroid, labels, density=200, smooth=0.5): """ Generate the parameter space plots """ try: def extraxt_points_from_grid(grid2D, parx=None, pary=None): """ Helper function that extract x,y(,z) points from all the data """ grid2D = grid2D.flatten() if parx is not None and pary is not None: points_x = np.array([ item["point"][parx] for item in grid2D if item["point"] is not None ]) points_y = np.array([ item["point"][pary] for item in grid2D if item["point"] is not None ]) points_z = np.array([ item["value"] for item in grid2D if item["point"] is not None ]) return points_x, points_y, points_z else: points_x = np.array([ item["point"] for item in grid2D if item["point"] is not None ]) points_y = np.array([ item["value"] for item in grid2D if item["point"] is not None ]) points_x = points_x.flatten() points_y = points_y.flatten() xy = np.array(list(zip(points_x, points_y)), dtype=[('x', float), ('y', float)]) xy.sort(order=['x'], axis=0) points_x = xy['x'] points_y = xy['y'] return points_x, points_y if self.num_params == 1: # Only one parameter refined: points_x, points_y = extraxt_points_from_grid(self.grid) ax = figure.add_subplot(1, 1, 1) ax.plot(points_x, points_y) ax.set_ylabel("Residual error") ax.set_xlabel(get_plot_safe(labels[0])) else: # Multi-parameter space: image_grid, divider, get_grid = self._setup_image_grid( figure, self.num_params) # Keep a reference to the images created, # so we can add a scale bar for all images (and they have the same range) ims = [] tvmin, tvmax = None, None for index, (parx, pary) in enumerate( itertools.combinations(list(range(self.num_params)), 2)): # Get the data for this cross section: grid2D = self.grid[index, ...] points_x, points_y, points_z = extraxt_points_from_grid( grid2D, parx, pary) # Setup axis: ax = get_grid(parx, pary) extent = (self.minima[parx], self.maxima[parx], self.minima[pary], self.maxima[pary]) aspect = 'auto' # Try to interpolate the data: xi = np.linspace(self.minima[parx], self.maxima[parx], density) yi = np.linspace(self.minima[pary], self.maxima[pary], density) zi = griddata((points_x, points_y), points_z, (xi[None, :], yi[:, None]), method='cubic') # Plot it: im = ax.imshow(zi, origin='lower', aspect=aspect, extent=extent, alpha=0.75) ims.append(im) im.set_cmap('gray_r') # Get visual limits: vmin, vmax = im.get_clim() if index == 0: tvmin, tvmax = vmin, vmax else: tvmin, tvmax = min(tvmin, vmin), max(tvmax, vmax) # Try to add a contour & labels: try: ct = ax.contour(xi, yi, zi, colors='k', aspect=aspect, extent=extent, origin='lower') ax.clabel(ct, colors='k', fontsize=10, format="%1.2f") except ValueError: pass #ignore the "zero-size array" error for now. # Add a red cross where the 'best' solution is: ax.plot((centroid[parx], ), (centroid[pary], ), 'r+') # Rotate x labels for lbl in ax.get_xticklabels(): lbl.set_rotation(90) # Reduce number of ticks: ax.locator_params(axis='both', nbins=5) # Set limits: ax.set_xlim(extent[0:2]) ax.set_ylim(extent[2:4]) # Add labels to the axes so the user knows which is which: # TODO add some flags/color/... indicating which phase & component each parameter belongs to... if parx == 0: ax.set_ylabel( str("#%d " % (pary + 1)) + get_plot_safe(labels[pary])) if pary == (self.num_params - 1): ax.set_xlabel( str("#%d " % (parx + 1)) + get_plot_safe(labels[parx])) # Set the data limits: for im in ims: im.set_clim(tvmin, tvmax) # Make it look PRO: if im is not None: cbar_ax = image_grid.cbar_axes[0] nx = 1 + (self.num_params - 1) * 2 ny1 = (self.num_params - 1) * 2 cbar_ax.set_axes_locator( divider.new_locator(nx=nx, ny=1, ny1=ny1)) cb = cbar_ax.colorbar(im) # @UnusedVariable except: print( "Unhandled exception while generating parameter space images:") print(format_exc()) # ignore error, tell the user via the plot and return self.clear_image(figure) return
def plot_images(self, figure, centroid, labels, density=200, smooth=0.5): """ Generate the parameter space plots """ try: def extraxt_points_from_grid(grid2D, parx=None, pary=None): """ Helper function that extract x,y(,z) points from all the data """ grid2D = grid2D.flatten() if parx is not None and pary is not None: points_x = np.array([item["point"][parx] for item in grid2D if item["point"] is not None]) points_y = np.array([item["point"][pary] for item in grid2D if item["point"] is not None]) points_z = np.array([item["value"] for item in grid2D if item["point"] is not None]) return points_x, points_y, points_z else: points_x = np.array([item["point"] for item in grid2D if item["point"] is not None]) points_y = np.array([item["value"] for item in grid2D if item["point"] is not None]) points_x = points_x.flatten() points_y = points_y.flatten() xy = np.array(list(zip(points_x, points_y)), dtype=[('x', float), ('y', float)]) xy.sort(order=['x'], axis=0) points_x = xy['x'] points_y = xy['y'] return points_x, points_y if self.num_params == 1: # Only one parameter refined: points_x, points_y = extraxt_points_from_grid(self.grid) ax = figure.add_subplot(1, 1, 1) ax.plot(points_x, points_y) ax.set_ylabel("Residual error") ax.set_xlabel(get_plot_safe(labels[0])) else: # Multi-parameter space: image_grid, divider, get_grid = self._setup_image_grid(figure, self.num_params) # Keep a reference to the images created, # so we can add a scale bar for all images (and they have the same range) ims = [] tvmin, tvmax = None, None for index, (parx, pary) in enumerate(itertools.combinations(list(range(self.num_params)), 2)): # Get the data for this cross section: grid2D = self.grid[index, ...] points_x, points_y, points_z = extraxt_points_from_grid(grid2D, parx, pary) # Setup axis: ax = get_grid(parx, pary) extent = ( self.minima[parx], self.maxima[parx], self.minima[pary], self.maxima[pary] ) aspect = 'auto' # Try to interpolate the data: xi = np.linspace(self.minima[parx], self.maxima[parx], density) yi = np.linspace(self.minima[pary], self.maxima[pary], density) zi = griddata((points_x, points_y), points_z, (xi[None, :], yi[:, None]), method='cubic') # Plot it: im = ax.imshow(zi, origin='lower', aspect=aspect, extent=extent, alpha=0.75) ims.append(im) im.set_cmap('gray_r') # Get visual limits: vmin, vmax = im.get_clim() if index == 0: tvmin, tvmax = vmin, vmax else: tvmin, tvmax = min(tvmin, vmin), max(tvmax, vmax) # Try to add a contour & labels: try: ct = ax.contour(xi, yi, zi, colors='k', aspect=aspect, extent=extent, origin='lower') ax.clabel(ct, colors='k', fontsize=10, format="%1.2f") except ValueError: pass #ignore the "zero-size array" error for now. # Add a red cross where the 'best' solution is: ax.plot((centroid[parx],), (centroid[pary],), 'r+') # Rotate x labels for lbl in ax.get_xticklabels(): lbl.set_rotation(90) # Reduce number of ticks: ax.locator_params(axis='both', nbins=5) # Set limits: ax.set_xlim(extent[0:2]) ax.set_ylim(extent[2:4]) # Add labels to the axes so the user knows which is which: # TODO add some flags/color/... indicating which phase & component each parameter belongs to... if parx == 0: ax.set_ylabel(str("#%d " % (pary + 1)) + get_plot_safe(labels[pary])) if pary == (self.num_params - 1): ax.set_xlabel(str("#%d " % (parx + 1)) + get_plot_safe(labels[parx])) # Set the data limits: for im in ims: im.set_clim(tvmin, tvmax) # Make it look PRO: if im is not None: cbar_ax = image_grid.cbar_axes[0] nx = 1 + (self.num_params - 1) * 2 ny1 = (self.num_params - 1) * 2 cbar_ax.set_axes_locator(divider.new_locator(nx=nx, ny=1, ny1=ny1)) cb = cbar_ax.colorbar(im) # @UnusedVariable except: print("Unhandled exception while generating parameter space images:") print(format_exc()) # ignore error, tell the user via the plot and return self.clear_image(figure) return