Source code for ADFWI.utils.assessment_metric

import numpy as np
from skimage.metrics import structural_similarity as ssim

[docs]def MSE(true_v, inv_v): """ Computes the Mean Squared Error (MSE) between the true velocity model and the inverted velocity model. Parameters ---------- true_v : numpy.ndarray The ground truth velocity model of shape (nz, nx). inv_v : numpy.ndarray The inverted velocity model of shape (nz, nx). Returns ------- float The sum of squared differences between the true and inverted velocity models. """ nz, nx = true_v.shape # Get the dimensions of the velocity models return np.sum((true_v - inv_v) ** 2) # Compute the sum of squared differences
[docs]def RMSE(true_v,inv_v): """ Computes the Root Mean Squared Error (RMSE) between the true velocity model and the inverted velocity model. Parameters ---------- true_v : numpy.ndarray The ground truth velocity model. Shape can be (nz, nx) or (batch, nz, nx). inv_v : numpy.ndarray The inverted velocity model. Shape should match `true_v`. Returns ------- numpy.ndarray or float If `true_v` has one less dimension than `inv_v`, returns an array of RMSE values for each sample in the batch. Otherwise, returns a single RMSE value. """ if len(true_v.shape) != len(inv_v.shape): true_v = true_v[np.newaxis,:,:] res = np.sqrt(np.sum((true_v-inv_v)**2,axis=(1,2))) return res else: return np.sqrt(np.sum((true_v-inv_v)**2))
[docs]def MAPE(true_v, inv_v): """ Computes the Mean Absolute Percentage Error (MAPE) between the true velocity model and the inverted velocity model. Parameters ---------- true_v : numpy.ndarray The ground truth velocity model. Shape can be (nz, nx) or (batch, nz, nx). inv_v : numpy.ndarray The inverted velocity model. Shape should match `true_v`. Returns ------- numpy.ndarray or float If `true_v` has one less dimension than `inv_v`, returns an array of MAPE values for each sample in the batch. Otherwise, returns a single MAPE value. """ if len(true_v.shape) != len(inv_v.shape): nz, nx = true_v.shape # Get spatial dimensions true_v = true_v[np.newaxis, :, :] # Add batch dimension if missing res = 100 / (nx * nz) * np.sum(np.abs(inv_v - true_v) / true_v, axis=(1, 2)) # Compute MAPE per batch else: nz, nx = true_v.shape[-2:] # Get spatial dimensions res = 100 / (nx * nz) * np.sum(np.abs(inv_v - true_v) / true_v) # Compute single MAPE value return res
[docs]def SSIM(true_v, inv_v, win_size=11): """ Computes the Structural Similarity Index (SSIM) between the true velocity model and the inverted velocity model. Parameters ---------- true_v : numpy.ndarray The ground truth velocity model. Shape can be (nz, nx) or (batch, nz, nx). inv_v : numpy.ndarray The inverted velocity model. Shape should match `true_v`. win_size : int, optional The size of the sliding window used for computing SSIM, by default 11. Returns ------- list or float If `true_v` has one less dimension than `inv_v`, returns a list of SSIM values for each sample in the batch. Otherwise, returns a single SSIM value. """ if len(true_v.shape) != len(inv_v.shape): ssim_res = [] for i in range(inv_v.shape[0]): vmax = np.max([true_v.max(), inv_v[i].max()]) # Compute max value for data range vmin = np.min([true_v.min(), inv_v[i].min()]) # Compute min value for data range temp_ssim = ssim(true_v, inv_v[i], data_range=vmax - vmin, win_size=win_size) ssim_res.append(temp_ssim) return ssim_res else: vmax = np.max([true_v.max(), inv_v.max()]) vmin = np.min([true_v.min(), inv_v.min()]) return ssim(true_v, inv_v, data_range=vmax - vmin, win_size=win_size)
[docs]def SNR(true_v, inv_v): """ Computes the Signal-to-Noise Ratio (SNR) between the true velocity model and the inverted velocity model. Parameters ---------- true_v : numpy.ndarray The ground truth velocity model. Shape can be (nz, nx) or (batch, nz, nx). inv_v : numpy.ndarray The inverted velocity model. Shape should match `true_v`. Returns ------- list or float If `true_v` has one less dimension than `inv_v`, returns a list of SNR values for each sample in the batch. Otherwise, returns a single SNR value. """ if len(true_v.shape) != len(inv_v.shape): snr_res = [] for i in range(inv_v.shape[0]): true_norm = np.sum(true_v ** 2) # Compute signal power diff_norm = np.sum((true_v - inv_v[i]) ** 2) # Compute noise power temp_snr = 10 * np.log10(true_norm / diff_norm) # Compute SNR in dB snr_res.append(temp_snr) return snr_res else: true_norm = np.sum(true_v ** 2) diff_norm = np.sum((true_v - inv_v) ** 2) temp_snr = 10 * np.log10(true_norm / diff_norm) return temp_snr