def run_script(json_payload): """ Calculates synthetic seismic data from a convolution model. Creates data for a cross section, angle gather, and wavelet gather. Inputs json_payload = {"earth_model": See ImageModel in modelr.api, "seismic": See SeismicModel in modelr.api, "trace": The trace number to use for the angle and wavelet gathers. "offset": The offset index to use for the wavelet and seismic cross section.} """ try: seismic = Seismic.from_json(json_payload["seismic"]) # parse json earth_model = ImageModelPersist.from_json(json_payload["earth_model"]) if earth_model.domain == 'time': earth_model.resample(seismic.dt) trace = json_payload["trace"] offset = json_payload["offset"] # seismic data = do_convolve( seismic.src, earth_model.rpp_t(seismic.dt)[..., offset][..., np.newaxis]).squeeze() # Hard coded, could be changed to be part of the seismic object f0 = 4.0 f1 = 100.0 f = np.logspace(max(np.log2(f0), np.log2(7)), np.log2(f1), 50, endpoint=True, base=2.0) duration = .3 wavelets = rotate_phase(seismic.wavelet(duration, seismic.dt, f), seismic.phase) wavelet_gather = do_convolve( wavelets, earth_model.rpp_t(seismic.dt)[..., trace, offset][..., np.newaxis, np.newaxis]).squeeze() offset_gather = do_convolve( seismic.src, earth_model.rpp_t(seismic.dt)[..., trace, :][..., np.newaxis, ...]).squeeze() if seismic.snr: wavelet_gather += noise_db(wavelet_gather, seismic.snr) offset_gather += noise_db(offset_gather, seismic.snr) data += noise_db(data, seismic.snr) # METADATA metadata = {} metadata["moduli"] = {} for rock in earth_model.get_rocks(): if rock.name not in metadata["moduli"]: metadata["moduli"][rock.name] = rock.moduli if earth_model.domain == "time": dt = earth_model.zrange / float(data.shape[0]) else: dt = seismic.dt * 1000.0 payload = { "seismic": data.T.tolist(), "dt": dt, "min": float(np.amin(data)), "max": float(np.amax(data)), "dx": earth_model.dx, "wavelet_gather": wavelet_gather.T.tolist(), "offset_gather": offset_gather.T.tolist(), "f": f.tolist(), "theta": earth_model.theta, "metadata": metadata } return payload except Exception as e: traceback.print_exc(file=sys.stdout)
def run_script(json_payload): # parse json fs_model = FluidSub1D.from_json(json_payload["earth_model"]) seismic = Seismic.from_json(json_payload["seismic"]) # extract rock properties vp, vs, rho = (fs_model.vp, fs_model.vs, fs_model.rho) vp_sub, vs_sub, rho_sub = fs_model.smith_sub() # convert to time dt = seismic.dt dz = fs_model.dz z = fs_model.z # use indices so we only run the algorithm once index = np.arange(vp.size, dtype=int) t_index = depth_to_time(index, vp, dz, dt).astype(int) sub_t_index = depth_to_time(index, vp_sub, dz, dt).astype(int) vp_t, vs_t, rho_t = (vp[t_index], vs[t_index], rho[t_index]) vp_sub_t, vs_sub_t, rho_sub_t = (vp_sub[sub_t_index], vs_sub[sub_t_index], rho_sub[sub_t_index]) # calculate reflectivities rpp = np.nan_to_num( np.array([ zoep(vp_t[:-1], vs_t[:-1], rho_t[:-1], vp_t[1:], vs_t[1:], rho_t[1:], float(theta)) for theta in seismic.theta[::-1] ]).T) rpp_sub = np.nan_to_num( np.array([ zoep(vp_sub_t[:-1], vs_sub_t[:-1], rho_sub_t[:-1], vp_sub_t[1:], vs_sub_t[1:], rho_sub_t[1:], float(theta)) for theta in seismic.theta[::-1] ]).T) # trim to be the same size n = min(rpp.shape[0], rpp_sub.shape[0]) rpp = rpp[:n, :] rpp_sub = rpp_sub[:n, :] t = np.arange(n) * dt # create synthetic seismic traces = np.squeeze(do_convolve(seismic.src, rpp[:, np.newaxis, :])) sub_traces = np.squeeze(do_convolve(seismic.src, rpp_sub[:, np.newaxis, :])) output = { "vp": vp.tolist(), "vs": vs.tolist(), "rho": rho.tolist(), "vp_sub": vp_sub.tolist(), "vs_sub": vs_sub.tolist(), "rho_sub": rho_sub.tolist(), "synth": np.nan_to_num(traces).T.tolist(), "synth_sub": np.nan_to_num(sub_traces).T.tolist(), "theta": seismic.theta, "rpp": rpp[:, 0].tolist(), "rpp_sub": rpp_sub[:, 0].tolist(), "t_lim": [float(np.amin(t)), float(np.amax(t))], "z_lim": [float(np.amin(z)), float(np.amax(z))], "vp_lim": [float(np.amin((vp, vp_sub))), float(np.amax((vp, vp_sub)))], "vs_lim": [float(np.amin((vs, vs_sub))), float(np.amax((vs, vs_sub)))], "rho_lim": [float(np.amin((rho, rho_sub))), float(np.amax((rho, rho_sub)))], "rpp_lim": [float(np.amin((rpp, rpp_sub))), float(np.amax((rpp, rpp_sub)))], "synth_lim": [ float(np.amin((traces, sub_traces))), float(np.amax((traces, sub_traces))) ], "dt": dt, "dz": dz } return output
def run_script(json_payload): """ Calculates synthetic seismic data from a convolution model. Creates data for a cross section, angle gather, and wavelet gather. Inputs json_payload = {"earth_model": See ImageModel in modelr.api, "seismic": See SeismicModel in modelr.api, "trace": The trace number to use for the angle and wavelet gathers. "offset": The offset index to use for the wavelet and seismic cross section.} """ try: seismic = Seismic.from_json(json_payload["seismic"]) # parse json earth_model = ImageModelPersist.from_json(json_payload["earth_model"]) if earth_model.domain == 'time': earth_model.resample(seismic.dt) trace = json_payload["trace"] offset = json_payload["offset"] ph = seismic.phase src = seismic.src # seismic data = do_convolve(src, earth_model.rpp_t(seismic.dt)[..., offset] [..., np.newaxis]).squeeze() # angle gather offset_gather = do_convolve(src, earth_model.rpp_t(seismic.dt)[..., trace, :] [..., np.newaxis, ...]).squeeze() # frequency gather f0 = 4.0 f1 = 100.0 f = np.logspace(max(np.log2(f0), np.log2(7)), np.log2(f1), 50, endpoint=True, base=2.0) wavelets = rotate_phase(seismic.wavelet(seismic.wavelet_duration, seismic.dt, f), ph, degrees=True) wavelet_gather = do_convolve(wavelets, earth_model.rpp_t(seismic.dt) [..., trace, offset] [..., np.newaxis, np.newaxis]).squeeze() # add noise if required if seismic.snr: data += noise_db(data, seismic.snr) offset_gather += noise_db(offset_gather, seismic.snr) wavelet_gather += noise_db(wavelet_gather, seismic.snr) # METADATA metadata = {} metadata["moduli"] = {} for rock in earth_model.get_rocks(): if rock.name not in metadata["moduli"]: metadata["moduli"][rock.name] = rock.moduli if earth_model.domain == "time": dt = earth_model.zrange / float(data.shape[0]) else: dt = seismic.dt * 1000.0 payload = {"seismic": data.T.tolist(), "dt": dt, "min": float(np.amin(data)), "max": float(np.amax(data)), "dx": earth_model.dx, "wavelet_gather": wavelet_gather.T.tolist(), "offset_gather": offset_gather.T.tolist(), "f": f.tolist(), "theta": earth_model.theta, "metadata": metadata} return payload except Exception as e: traceback.print_exc(file=sys.stdout)
def run_script(json_payload): # parse json fs_model = FluidSub1D.from_json(json_payload["earth_model"]) seismic = Seismic.from_json(json_payload["seismic"]) # extract rock properties vp, vs, rho = (fs_model.vp, fs_model.vs, fs_model.rho) vp_sub, vs_sub, rho_sub = fs_model.smith_sub() # convert to time dt = seismic.dt dz = fs_model.dz z = fs_model.z # use indices so we only run the algorithm once index = np.arange(vp.size, dtype=int) t_index = depth_to_time(index, vp, dz, dt).astype(int) sub_t_index = depth_to_time(index, vp_sub, dz, dt).astype(int) vp_t, vs_t, rho_t = (vp[t_index], vs[t_index], rho[t_index]) vp_sub_t, vs_sub_t, rho_sub_t = (vp_sub[sub_t_index], vs_sub[sub_t_index], rho_sub[sub_t_index]) # calculate reflectivities rpp = np.nan_to_num(np.array([zoep(vp_t[:-1], vs_t[:-1], rho_t[:-1], vp_t[1:], vs_t[1:], rho_t[1:], float(theta)) for theta in seismic.theta[::-1]]).T) rpp_sub = np.nan_to_num(np.array([zoep(vp_sub_t[:-1], vs_sub_t[:-1], rho_sub_t[:-1], vp_sub_t[1:], vs_sub_t[1:], rho_sub_t[1:], float(theta)) for theta in seismic.theta[::-1]]).T) # trim to be the same size n = min(rpp.shape[0], rpp_sub.shape[0]) rpp = rpp[:n, :] rpp_sub = rpp_sub[:n, :] t = np.arange(n) * dt # create synthetic seismic traces = np.squeeze(do_convolve(seismic.src, rpp[:, np.newaxis, :])) sub_traces = np.squeeze(do_convolve(seismic.src, rpp_sub[:, np.newaxis, :])) output = {"vp": vp.tolist(), "vs": vs.tolist(), "rho": rho.tolist(), "vp_sub": vp_sub.tolist(), "vs_sub": vs_sub.tolist(), "rho_sub": rho_sub.tolist(), "synth": np.nan_to_num(traces).T.tolist(), "synth_sub": np.nan_to_num(sub_traces).T.tolist(), "theta": seismic.theta, "rpp": rpp[:, 0].tolist(), "rpp_sub": rpp_sub[:, 0].tolist(), "t_lim": [float(np.amin(t)), float(np.amax(t))], "z_lim": [float(np.amin(z)), float(np.amax(z))], "vp_lim": [float(np.amin((vp, vp_sub))), float(np.amax((vp, vp_sub)))], "vs_lim": [float(np.amin((vs, vs_sub))), float(np.amax((vs, vs_sub)))], "rho_lim": [float(np.amin((rho, rho_sub))), float(np.amax((rho, rho_sub)))], "rpp_lim": [float(np.amin((rpp, rpp_sub))), float(np.amax((rpp, rpp_sub)))], "synth_lim": [float(np.amin((traces, sub_traces))), float(np.amax((traces, sub_traces)))], "dt": dt, "dz": dz} return output