def dipole_map_value(fld, pts, r=1.0, fillna=None, cotr=None, crd_system=None, interp_kind='linear'): """Map values assuming they're constant along ideal dipole lines Args: fld (Field): values to interpolate onto the mapped pts pts (ndarray): 3xN for N (x, y, z) points that will be mapped r (float): radius of resulting map cotr (None): if given, use cotr to perform mapping in sm crd_system (str): crd system of pts interp_kind (str): how to interpolate fld onto source points Returns: ndarray: ndarray of mapped values, one for each of the N points """ if crd_system is None: crd_system = viscid.as_crd_system(fld, 'gse') if fld.is_spherical: # TODO: verify that crd_system works as expected for ionosphere # fields (ie, meaning of +x and phi = 0) fld = viscid.as_spherefield(fld, order=('theta', 'phi'))['r=newaxis, ...'] else: pass # pts should be shaped 3xNX*NY*NZ or similar such that the points # are in the same order as the flattened c-contiguous array mapped_pts = dipole_map(pts, r=r, cotr=cotr, crd_system=crd_system, as_spherical=fld.is_spherical) ret = viscid.interp(fld, mapped_pts, kind=interp_kind, wrap=False) if fillna is not None: ret[np.isnan(ret)] = fillna return ret
def run_test(fld, seeds, kind, show=False): plt.clf() vlt.plot(viscid.interp(fld, seeds, kind=kind)) plt.title(kind) plt.savefig(next_plot_fname(__file__)) if show: vlt.show()
def integrate_along_lines(lines, fld, reduction="dot", mask_func=None, interp_kind='trilin'): """Integrate the value of fld along a list of lines Args: lines (list): list of 3xN ndarrays, N needs not be the same for all lines fld (Field): Field to interpolate / integrate reduction (str): If fld is a vector field, what quantity to integrate. Can be "dot" to dot the vectors with ds along the line, or "mag" to integrate the magnitude. interp_kind (str): which interpolation to use, const or trilin Returns: ndarray with shape (len(lines), ) """ arr = np.zeros((len(lines), ), dtype=fld.dtype) cum_n = np.cumsum([0] + [line.shape[1] for line in lines]) all_verts = np.concatenate(lines, axis=1) fld_on_verts = viscid.interp(fld, all_verts, kind=interp_kind).data for i, start, stop in izip(count(), cum_n[:-1], cum_n[1:]): ds = np.linalg.norm(lines[i][:, 1:] - lines[i][:, :-1], axis=0) if len(fld_on_verts.shape) > 1: reduction = reduction.strip().lower() if reduction == "dot": dsvec = lines[i][:, 1:] - lines[i][:, :-1] dsvec = dsvec / np.linalg.norm(dsvec, axis=0) values = 0.5 * (fld_on_verts[start:stop - 1, :] + fld_on_verts[start + 1:stop, :]) values = values * dsvec.T if mask_func is not None: values = np.ma.masked_where(mask_func(values), values) values = np.sum(values, axis=1) elif reduction in ["mag", "magnitude", "norm"]: mag = np.linalg.norm(fld_on_verts[start:stop], axis=1) values = 0.5 * (mag[start:stop - 1] + mag[start + 1:stop]) else: raise ValueError("Unknown reduction: {0}".format(reduction)) else: values = 0.5 * (fld_on_verts[start:stop - 1] + fld_on_verts[start + 1:stop]) arr[i] = np.sum(values * ds) return arr
def integrate_along_lines(lines, fld, reduction="dot", mask_func=None, interp_kind='trilin'): """Integrate the value of fld along a list of lines Args: lines (list): list of 3xN ndarrays, N needs not be the same for all lines fld (Field): Field to interpolate / integrate reduction (str): If fld is a vector field, what quantity to integrate. Can be "dot" to dot the vectors with ds along the line, or "mag" to integrate the magnitude. interp_kind (str): which interpolation to use, const or trilin Returns: ndarray with shape (len(lines), ) """ arr = np.zeros((len(lines),), dtype=fld.dtype) cum_n = np.cumsum([0] + [line.shape[1] for line in lines]) all_verts = np.concatenate(lines, axis=1) fld_on_verts = viscid.interp(fld, all_verts, kind=interp_kind).data for i, start, stop in izip(count(), cum_n[:-1], cum_n[1:]): ds = np.linalg.norm(lines[i][:, 1:] - lines[i][:, :-1], axis=0) if len(fld_on_verts.shape) > 1: reduction = reduction.strip().lower() if reduction == "dot": dsvec = lines[i][:, 1:] - lines[i][:, :-1] dsvec = dsvec / np.linalg.norm(dsvec, axis=0) values = 0.5 * (fld_on_verts[start:stop - 1, :] + fld_on_verts[start + 1:stop, :]) values = values * dsvec.T if mask_func is not None: values = np.ma.masked_where(mask_func(values), values) values = np.sum(values, axis=1) elif reduction in ["mag", "magnitude", "norm"]: mag = np.linalg.norm(fld_on_verts[start:stop], axis=1) values = 0.5 * (mag[start:stop - 1] + mag[start + 1:stop]) else: raise ValueError("Unknown reduction: {0}".format(reduction)) else: values = 0.5 * (fld_on_verts[start:stop - 1] + fld_on_verts[start + 1:stop]) arr[i] = np.sum(values * ds) return arr
def project_along_line(line, fld, interp_kind='trilin'): """Project a Vector Field Parallel to a streamline Args: line (ndarray): 3xN of points along the fld (VectorField): Field to interpolate and project onto the line interp_kind (str): which interpolation to use, const or trilin """ fld_on_verts = viscid.interp(fld, line, kind=interp_kind) # FIXME: here in lies a bug, which axis am I actually summing over? # maybe that's not the bug, but there must be something wrong # here as indicated by kris_scripts/work/iono_xi_mismatch/analytic_pot.py dsvec = line[:, 2:] - line[:, :-2] dsvec = np.concatenate([dsvec[:, 0:1], dsvec, dsvec[:, -2:-1]], axis=1) dsvec = dsvec / np.linalg.norm(dsvec, axis=0) return np.sum(fld_on_verts * dsvec.T, axis=1)