예제 #1
0
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)
예제 #2
0
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
예제 #3
0
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)
예제 #4
0
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