def gaussian(self, darray, sigmas=(1, 1, 1), preview=None): """ Description ----------- Perform gaussian smoothing of input seismic Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- sigmas : tuple (len 3), smoothing parameters in I, J, K preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ # Generate Dask Array as necessary and perform algorithm kernel = tuple((np.array(sigmas) * 2.5).astype(int)) darray, chunks_init = self.create_array(darray, kernel, preview=preview) result = darray.map_blocks(ndi.gaussian_filter, sigma=sigmas, dtype=darray.dtype) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return(result)
def envelope(self, darray, preview=None): """ Description ----------- Compute the Envelope of the input data Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ kernel = (1, 1, 25) darray, chunks_init = self.create_array(darray, kernel, preview=preview) analytical_trace = darray.map_blocks(util.hilbert, dtype=darray.dtype) result = da.absolute(analytical_trace) result = util.trim_dask_array(result, kernel) return (result)
def gradient_magnitude(self, darray, sigmas=(1, 1, 1), preview=None): """ Description ----------- Compute the 3D Gradient Magnitude using a Gaussian Operator Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- sigmas : tuple (len 3), gaussian operator in I, J, K preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ kernel = tuple(2 * (4 * np.array(sigmas) + 0.5).astype(int) + 1) darray, chunks_init = self.create_array(darray, kernel, preview=preview) result = darray.map_blocks(ndi.gaussian_gradient_magnitude, sigma=sigmas, dtype=darray.dtype) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return (result)
def convolution(self, darray, kernel=(3, 3, 3), preview=None): """ Description ----------- Perform convolution smoothing of input seismic data Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- kernel : tuple (len 3), operator size in I, J, K preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ # Generate Dask Array as necessary and perform algorithm darray, chunks_init = self.create_array(darray, kernel, preview=preview) result = darray.map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return(result)
def eig_complex(self, darray, kernel=(3, 3, 9), preview=None): """ Description ----------- Compute multi-trace semblance from 3D seismic incorporating the analytic trace Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- kernel : tuple (len 3), operator size preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ # Function to compute the COV def cov(x, ki, kj, kk): x = x.reshape((ki * kj, kk)) x = np.hstack([x.real, x.imag]) return (x.dot(x.T)) # Function to extract patches and perform algorithm def operation(chunk, kernel): np.seterr(all='ignore') ki, kj, kk = kernel patches = util.extract_patches(chunk, kernel) out_data = [] for i in range(0, patches.shape[0]): traces = patches[i] traces = traces.reshape(-1, ki * kj * kk) cov = np.apply_along_axis(cov, 1, traces, ki, kj, kk) vals = np.linalg.eigvals(cov) vals = np.abs(vals.max(axis=1) / vals.sum(axis=1)) out_data.append(vals) out_data = np.asarray(out_data).reshape(patches.shape[:3]) return (out_data) # Generate Dask Array as necessary and perform algorithm darray, chunks_init = self.create_array(darray, kernel, preview) hilbert = darray.map_blocks(util.hilbert, dtype=darray.dtype) result = hilbert.map_blocks(operation, kernel=kernel, dtype=darray.dtype) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return (result)
def first_derivative(self, darray, axis=-1, preview=None): """ Description ----------- Compute first derivative of seismic data in specified direction Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- axis : Number, axis dimension preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ kernel = (3,3,3) axes = [ax for ax in range(darray.ndim) if ax != axis] darray, chunks_init = self.create_array(darray, kernel, preview=preview) result0 = darray.map_blocks(ndi.correlate1d, weights=[-0.5, 0, 0.5], axis=axis, dtype=darray.dtype) result1 = result0.map_blocks(ndi.correlate1d, weights=[0.178947,0.642105,0.178947], axis=axes[0], dtype=darray.dtype) result2 = result1.map_blocks(ndi.correlate1d, weights=[0.178947,0.642105,0.178947], axis=axes[1], dtype=darray.dtype) result = util.trim_dask_array(result2, kernel) return(result)
def phase_rotation(self, darray, rotation, preview=None): """ Description ----------- Rotate the phase of the seismic data by a specified angle Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays rotation : Number (degrees), angle of rotation Keywork Arguments ----------------- preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ phi = np.deg2rad(rotation) kernel = (1,1,25) darray, chunks_init = self.create_array(darray, kernel, preview=preview) analytical_trace = darray.map_blocks(signal.hilbert, dtype=darray.dtype) result = analytical_trace.real * da.cos(phi) - analytical_trace.imag * da.sin(phi) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return(result)
def rms(self, darray, kernel=(1, 1, 9), preview=None): """ Description ----------- Compute the Root Mean Squared (RMS) value within a specified window Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- kernel : tuple (len 3), operator size preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ # Function to extract patches and perform algorithm def operation(chunk, kernel): x = util.extract_patches(chunk, kernel) out = np.sqrt(np.mean(x**2, axis=(-3, -2, -1))) return (out) darray, chunks_init = self.create_array(darray, kernel, preview=preview) result = darray.map_blocks(operation, kernel=kernel, dtype=darray.dtype, chunks=darray.chunks) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return (result)
def volume_curvature(self, darray_il, darray_xl, dip_factor=10, kernel=(3, 3, 3), preview=None): """ Description ----------- Compute volume curvature attributes from 3D seismic dips Parameters ---------- darray_il : Array-like, Inline dip - acceptable inputs include Numpy, HDF5, or Dask Arrays darray_xl : Array-like, Crossline dip - acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- dip_factor : Number, scalar for dip values kernel : tuple (len 3), operator size preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- H, K, Kmax, Kmin, KMPos, KMNeg : Dask Array, {H : 'Mean Curvature', K : 'Gaussian Curvature', Kmax : 'Max Curvature', Kmin : 'Min Curvature', KMPos : Most Positive Curvature, KMNeg : Most Negative Curvature} """ np.seterr(all='ignore') # Generate Dask Array as necessary darray_il, chunks_init = self.create_array(darray_il, kernel, preview=preview) darray_xl, chunks_init = self.create_array(darray_xl, kernel, preview=preview) u = -darray_il / dip_factor v = -darray_xl / dip_factor w = da.ones_like(u, chunks=u.chunks) # Compute Gradients ux = sp().first_derivative(u, axis=0) uy = sp().first_derivative(u, axis=1) uz = sp().first_derivative(u, axis=2) vx = sp().first_derivative(v, axis=0) vy = sp().first_derivative(v, axis=1) vz = sp().first_derivative(v, axis=2) # Smooth Gradients ux = ux.map_blocks(ndi.uniform_filter, size=kernel, dtype=ux.dtype) uy = uy.map_blocks(ndi.uniform_filter, size=kernel, dtype=ux.dtype) uz = uz.map_blocks(ndi.uniform_filter, size=kernel, dtype=ux.dtype) vx = vx.map_blocks(ndi.uniform_filter, size=kernel, dtype=ux.dtype) vy = vy.map_blocks(ndi.uniform_filter, size=kernel, dtype=ux.dtype) vz = vz.map_blocks(ndi.uniform_filter, size=kernel, dtype=ux.dtype) u = util.trim_dask_array(u, kernel) v = util.trim_dask_array(v, kernel) w = util.trim_dask_array(w, kernel) ux = util.trim_dask_array(ux, kernel) uy = util.trim_dask_array(uy, kernel) uz = util.trim_dask_array(uz, kernel) vx = util.trim_dask_array(vx, kernel) vy = util.trim_dask_array(vy, kernel) vz = util.trim_dask_array(vz, kernel) wx = da.zeros_like(ux, chunks=ux.chunks, dtype=ux.dtype) wy = da.zeros_like(ux, chunks=ux.chunks, dtype=ux.dtype) wz = da.zeros_like(ux, chunks=ux.chunks, dtype=ux.dtype) uv = u * v vw = v * w u2 = u * u v2 = v * v w2 = w * w u2pv2 = u2 + v2 v2pw2 = v2 + w2 s = da.sqrt(u2pv2 + w2) # Measures of surfaces E = da.ones_like(u, chunks=u.chunks, dtype=u.dtype) F = -(u * w) / (da.sqrt(u2pv2) * da.sqrt(v2pw2)) G = da.ones_like(u, chunks=u.chunks, dtype=u.dtype) D = -(-uv * vx + u2 * vy + v2 * ux - uv * uy) / (u2pv2 * s) Di = -(vw * (uy + vx) - 2 * u * w * vy - v2 * (uz + wx) + uv * (vz + wy)) / (2 * da.sqrt(u2pv2) * da.sqrt(v2pw2) * s) Dii = -(-vw * wy + v2 * wz + w2 * vy - vw * vz) / (v2pw2 * s) H = (E * Dii - 2 * F * Di + G * D) / (2 * (E * G - F * F)) K = (D * Dii - Di * Di) / (E * G - F * F) Kmin = H - da.sqrt(H * H - K) Kmax = H + da.sqrt(H * H - K) H[da.isnan(H)] = 0 K[da.isnan(K)] = 0 Kmax[da.isnan(Kmax)] = 0 Kmin[da.isnan(Kmin)] = 0 KMPos = da.maximum(Kmax, Kmin) KMNeg = da.minimum(Kmax, Kmin) return (H, K, Kmax, Kmin, KMPos, KMNeg)
def chaos(self, darray, kernel=(3, 3, 9), preview=None): """ Description ----------- Compute multi-trace chaos from 3D seismic Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- kernel : tuple (len 3), operator size preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- result : Dask Array """ # Function to extract patches and perform algorithm def operation(gi2, gj2, gk2, gigj, gigk, gjgk): np.seterr(all='ignore') chunk_shape = gi2.shape gst = np.array([[gi2, gigj, gigk], [gigj, gj2, gjgk], [gigk, gjgk, gk2]]) gst = np.moveaxis(gst, [0, 1], [-2, -1]) gst = gst.reshape((-1, 3, 3)) eigs = np.sort(np.linalg.eigvalsh(gst)) e1 = eigs[:, 2].reshape(chunk_shape) e2 = eigs[:, 1].reshape(chunk_shape) e3 = eigs[:, 0].reshape(chunk_shape) out = (2 * e2) / (e1 + e3) return (out) # Generate Dask Array as necessary darray, chunks_init = self.create_array(darray, kernel, preview) # Compute I, J, K gradients gi = sp().first_derivative(darray, axis=0) gj = sp().first_derivative(darray, axis=1) gk = sp().first_derivative(darray, axis=2) # Compute the Inner Product of the Gradients gi2 = (gi * gi).map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) gj2 = (gj * gj).map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) gk2 = (gk * gk).map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) gigj = (gi * gj).map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) gigk = (gi * gk).map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) gjgk = (gj * gk).map_blocks(ndi.uniform_filter, size=kernel, dtype=darray.dtype) result = da.map_blocks(operation, gi2, gj2, gk2, gigj, gigk, gjgk, dtype=darray.dtype) result = util.trim_dask_array(result, kernel) result[da.isnan(result)] = 0 return (result)
def gradient_structure_tensor(self, darray, kernel, preview=None): """ Description ----------- Convience function to compute the Inner Product of Gradients Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays kernel : tuple (len 3), operator size Keywork Arguments ----------------- preview : str, enables or disables preview mode and specifies direction Acceptable inputs are (None, 'inline', 'xline', 'z') Optimizes chunk size in different orientations to facilitate rapid screening of algorithm output Returns ------- gi2, gj2, gk2, gigj, gigk, gjgk : Dask Array """ # Generate Dask Array as necessary darray, chunks_init = self.create_array(darray, kernel, preview=preview) # Compute I, J, K gradients gi = sp().first_derivative(darray, axis=0) gj = sp().first_derivative(darray, axis=1) gk = sp().first_derivative(darray, axis=2) gi = util.trim_dask_array(gi, kernel) gj = util.trim_dask_array(gj, kernel) gk = util.trim_dask_array(gk, kernel) # Compute Inner Product of Gradients hw = tuple(np.array(kernel) // 2) gi2 = (gi * gi).map_overlap(ndi.uniform_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) gj2 = (gj * gj).map_overlap(ndi.uniform_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) gk2 = (gk * gk).map_overlap(ndi.uniform_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) gigj = (gi * gj).map_overlap(ndi.uniform_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) gigk = (gi * gk).map_overlap(ndi.uniform_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) gjgk = (gj * gk).map_overlap(ndi.uniform_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) return (gi2, gj2, gk2, gigj, gigk, gjgk)