File size: 3,676 Bytes
9ea4f07
 
 
 
 
 
 
 
c18aa6e
 
e714924
 
c18aa6e
 
556dce2
c18aa6e
e714924
c18aa6e
 
556dce2
c18aa6e
e714924
c18aa6e
 
 
 
 
 
e714924
 
 
 
c18aa6e
 
 
 
 
 
 
556dce2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c18aa6e
556dce2
 
 
 
fea26d8
c18aa6e
556dce2
 
 
 
 
 
0594cff
 
 
556dce2
 
 
 
 
 
 
 
 
 
 
 
e714924
 
556dce2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613439c
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import streamlit as st
import bruges as b
from einops import repeat
import numpy as np
from bruges.reflection.reflection import zoeppritz_rpp as zrpp
import pandas as pd
import altair as alt


def vs_from_poisson(vp, poisson):
    '''compute pressure velocity from
    shear velocity and poissons ratio'''
    return np.sqrt((vp**2 - 2*poisson*vp**2)/(2 - 2*poisson))


def gardners(vp):
    '''compute density via gardners relation'''
    return 1000*0.31*np.power(vp, 0.25)/1.33


def cartesian_product(*arrays):
    '''return cartesion product of several arrays'''
    ndim = len(arrays)
    return (np.stack(np.meshgrid(*arrays), axis=-1)
              .reshape(-1, ndim))


def loop_zrpp(vp1,vs1,rho1,vp2,vs2,rho2,theta1):
    '''compute reflectivity for many values of
    input parameters.
    "1" denotes layer one, "2" denotes layer two.
    outside this function, I tend to use 0-indexing though.'''
    refl_loop = np.empty(len(vp1), dtype=complex)
    for i in range(vp1.shape[0]):
        refl_loop[i] = zrpp(vp1=vp1[i], vs1=vs1[i], rho1=rho1[i],
                         vp2=vp2[i], vs2=vs2[i], rho2=rho2[i],
                         theta1=theta1[i])
    return refl_loop

def wb_ava_fig(vwater=1520., rwater = 1025., poissons=0.49):
    '''
    AVO: Amplitude Versus Offset
    AVA: Amplitude Versus Angle
    compute AVA at the WB for a range of values,
    then plot using altair
    '''
    ### Set up some variables
    VP1 = np.arange(1530,1820,50)
    THE = np.arange(0.0, 88., 1.)
    POI = np.array([poissons])
    
    ### Set variables that depend on those variables
    params = cartesian_product(VP1, THE, POI)
    VP1, THE, POI = [a.ravel() for a in np.hsplit(params, 3)]
    VP0 = np.full(VP1.shape, vwater)
    # V-RMS for ~200 m water depth
    VS0 = np.full(VP1.shape, 0.)
    RH0 = np.full(VP1.shape, rwater)
    # 1025 kg/m^3 per Inversion of the physical properties of seafloor surface, South China Sea, Zhou et al 2021
    VP1 = VP1
    VS1 = vs_from_poisson(VP1,POI)
    RH1 = gardners(VP1)
    
    ### Shove into a dict to pass to zrpp
    params = {"vp1": VP0, "vs1": VS0, "rho1": RH0,
          "vp2": VP1, "vs2": VS1, "rho2": RH1,
          "theta1":THE}

    # Compute zoeppritz equation
    r = loop_zrpp(**params)
    
    # Put the results into a DataFrame
    df = pd.DataFrame({"Vp sub-WB": VP1, "Poisson_s ratio": POI, "Vs sub-WB": VS1,
                   "Angle": THE, "Amplitude": np.real(r)})
    
    # Select only points pre-critical angle
    df["Ang_Crit"] = np.degrees(np.arcsin(1500 / df["Vp sub-WB"].values))
    df = df[df["Angle"] < df["Ang_Crit"]]
    
    # Create the altair figure
    highlight = alt.selection(type='single', on='mouseover',
                          fields=["Vp sub-WB:Q"], nearest=True)

    base = alt.Chart(df).encode(
            x="Angle",
            y="Amplitude",
            color="Vp sub-WB:Q",
            tooltip=["Vp sub-WB", "Vs sub-WB", "Angle", "Amplitude"]
    )

    points = base.mark_circle().encode(
        opacity=alt.value(0)
    ).add_selection(
        highlight
    ).properties(
        width=600,
        height=450
    )

    lines = base.mark_line().encode(
        size=alt.condition(~highlight, alt.value(3), alt.value(7))
    )
    
    return points + lines

vwater = st.slider("Select a value for water velocity", min_value=1495, max_value=1545, value=1520)
rwater = st.slider("Select a value for density of water", min_value=1005, max_value=1045, value=1025)
poissons = st.slider("Select a value for Poisson's ratio", min_value=0.4, max_value=0.5, value=0.48)
# st.write("Poisson's ratio is:", p)


st.altair_chart(wb_ava_fig(vwater, rwater, poissons))