def instantaneous_frequency(self, darray, sample_rate=4, preview=None): """ Description ----------- Compute the Instantaneous Frequency of the input data Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- sample_rate : Number, sample rate in milliseconds (ms) 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 """ darray, chunks_init = self.create_array(darray, preview=preview) fs = 1000 / sample_rate phase = self.instantaneous_phase(darray) phase = da.deg2rad(phase) phase = phase.map_blocks(np.unwrap, dtype=darray.dtype) phase_prime = sp().first_derivative(phase, axis=-1) result = da.absolute((phase_prime / (2.0 * np.pi) * fs)) return (result)
def frequency_change(self, darray, sample_rate=4, preview=None): """ Description ----------- Compute the Frequency Change of the input data Parameters ---------- darray : Array-like, acceptable inputs include Numpy, HDF5, or Dask Arrays Keywork Arguments ----------------- sample_rate : Number, sample rate in milliseconds (ms) 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 """ darray, chunks_init = self.create_array(darray, preview=preview) inst_freq = self.instantaneous_frequency(darray, sample_rate) result = sp().first_derivative(inst_freq, axis=-1) return (result)
def amplitude_acceleration(self, darray, preview=None): """ Description ----------- Compute the Amplitude Acceleration 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 """ darray, chunks_init = self.create_array(darray, preview=preview) rac = self.relative_amplitude_change(darray) result = sp().first_derivative(rac, axis=-1) 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_dips(self, darray, dip_factor=10, kernel=(3, 3, 3), preview=None): """ Description ----------- Compute Inline and Crossline Dip from the Inline, Crossline, & Z Gradients Parameters ---------- darray : Array-like, 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 ------- il_dip : Dask Array, Inline Dips xl_dip : Dask Array, Crossline Dips """ # Generate Dask Array as necessary darray, chunks_init = self.create_array(darray, kernel=None, 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) # Compute dips il_dip = -(gi / gk) * dip_factor xl_dip = -(gj / gk) * dip_factor il_dip[da.isnan(il_dip)] = 0 xl_dip[da.isnan(xl_dip)] = 0 # Perform smoothing as specified if kernel != None: hw = tuple(np.array(kernel) // 2) il_dip = il_dip.map_overlap(ndi.median_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) xl_dip = xl_dip.map_overlap(ndi.median_filter, depth=hw, boundary='reflect', dtype=darray.dtype, size=kernel) return (il_dip, xl_dip)
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)