obspy中文教程(二)

由于篇幅过长,一共分为八个文档,此为第二部分,内容如下目录:

Downsampling Seismograms(下采样)

Merging Seismograms(合并)

Beamforming - FK Analysis (FK分析)

Plotting Spectrograms(绘制频谱图)


Downsampling Seismograms(下采样)

下面的脚本展示了如何对地震记录进行下采样。目前支持简单的整数下采样。如果未明确禁用,则在下采样之前应先进行低通滤波以防产生混叠。为了比较,也绘制了过滤过的未下采样数据。应用的处理步骤记录在每个Trace的trace.stats.processing中。请注意处理开始的相位,因为默认情况下应用的滤波器不是零相位类型。这可以通过手动应用零相滤波器并在下下采样期间停用自动滤波来避免(no_filter = True)。

import numpy as np

import matplotlib.pyplot as plt

import obspy

# Read the seismogram

st = obspy.read("https://examples.obspy.org/RJOB_061005_072159.ehz.new")

# There is only one trace in the Stream object, let’s work on that trace...

tr = st[0]

# Decimate the 200 Hz data by a factor of 4 to 50 Hz. Note that this

# automatically includes a lowpass filtering with corner frequency 20 Hz.

# We work on a copy of the original data just to demonstrate the effects of

# downsampling.

tr_new = tr.copy()

tr_new.decimate(factor=4, strict_length=False)

# For comparison also only filter the original data (same filter options as in

# automatically applied filtering during downsampling, corner frequency

# 0.4 * new sampling rate)

tr_filt = tr.copy()

tr_filt.filter(’lowpass’, freq=0.4 * tr.stats.sampling_rate / 4.0)

# Now let’s plot the raw and filtered data...

t = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta)

t_new = np.arange(0, tr_new.stats.npts / tr_new.stats.sampling_rate,tr_new.stats.delta)

plt.plot(t, tr.data, ’k’, label=’Raw’, alpha=0.3)

plt.plot(t, tr_filt.data, ’b’, label=’Lowpassed’, alpha=0.7)

plt.plot(t_new, tr_new.data, ’r’, label=’Lowpassed/Downsampled’, alpha=0.7)

plt.xlabel(’Time [s]’)

plt.xlim(82, 83.5)

plt.suptitle(tr.stats.starttime)

plt.legend()

plt.show()

Merging Seismograms(合并)

下面的例子显示了如何合并然后绘制三个重叠的地震图,最长的一个被认为是正确的。 请参阅merge()方法的文档。

import numpy as np

import matplotlib.pyplot as plt

import obspy

# Read in all files starting with dis.

st = obspy.read("https://examples.obspy.org/dis.G.SCZ.__.BHE")

st += obspy.read("https://examples.obspy.org/dis.G.SCZ.__.BHE.1")

st += obspy.read("https://examples.obspy.org/dis.G.SCZ.__.BHE.2")

# sort

st.sort([’starttime’])

# start time in plot equals 0

dt = st[0].stats.starttime.timestamp

# Go through the stream object, determine time range in julian seconds

# and plot the data with a shared x axis

ax = plt.subplot(4, 1, 1) # dummy for tying axis

for i in range(3):

    plt.subplot(4, 1, i + 1, sharex=ax)

    t = np.linspace(st[i].stats.starttime.timestamp - dt,st[i].stats.endtime.timestamp - dt,st[i].stats.npts)

plt.plot(t, st[i].data)

# Merge the data together and show plot in a similar way

st.merge(method=1)

plt.subplot(4, 1, 4, sharex=ax)

t = np.linspace(st[0].stats.starttime.timestamp - dt,

st[0].stats.endtime.timestamp - dt,

st[0].stats.npts)

plt.plot(t, st[0].data, ’r’)

plt.show()

Beamforming - FK Analysis (FK分析)

下列代码展示了如何使用obspy进行FK分析。这些数据来自····

我们应用下列设置执行array_processing():

  1. 设置慢度网络拐点-3.0:3.0s/km,步长sl_s=0.03
  2. 窗口长1s,步长0.05
  3. 数据经过1~8Hz的带通滤波,不使用预白化
  4. semb_thres和vel_thres设置为无穷小的数字,不得更改。
  5. 时间戳timestamp设置为“mlabday”他可以被我们的绘图程序直接读取
  6. stime和etime定为UTCDate Time格式

输出被存储在out中。

下半部分展示了如何绘制输出。我们使用array_processing()输出的out,它是包含了时间戳、相对功率、绝对功率、反量和慢度的numpy ndarray。色条代表相对功率。

import matplotlib.pyplot as plt

import matplotlib.dates as mdates



import obspy

from obspy.core.util import AttribDict

from obspy.imaging.cm import obspy_sequential

from obspy.signal.invsim import corn_freq_2_paz

from obspy.signal.array_analysis import array_processing





# Load data

st = obspy.read("https://examples.obspy.org/agfa.mseed")



# Set PAZ and coordinates for all 5 channels

st[0].stats.paz = AttribDict({

    'poles': [(-0.03736 - 0.03617j), (-0.03736 + 0.03617j)],

    'zeros': [0j, 0j],

    'sensitivity': 205479446.68601453,

    'gain': 1.0})

st[0].stats.coordinates = AttribDict({

    'latitude': 48.108589,

    'elevation': 0.450000,

    'longitude': 11.582967})



st[1].stats.paz = AttribDict({

    'poles': [(-0.03736 - 0.03617j), (-0.03736 + 0.03617j)],

    'zeros': [0j, 0j],

    'sensitivity': 205479446.68601453,

    'gain': 1.0})

st[1].stats.coordinates = AttribDict({

    'latitude': 48.108192,

    'elevation': 0.450000,

    'longitude': 11.583120})



st[2].stats.paz = AttribDict({

    'poles': [(-0.03736 - 0.03617j), (-0.03736 + 0.03617j)],

    'zeros': [0j, 0j],

    'sensitivity': 250000000.0,

    'gain': 1.0})

st[2].stats.coordinates = AttribDict({

    'latitude': 48.108692,

    'elevation': 0.450000,

    'longitude': 11.583414})



st[3].stats.paz = AttribDict({

    'poles': [(-4.39823 + 4.48709j), (-4.39823 - 4.48709j)],

    'zeros': [0j, 0j],

    'sensitivity': 222222228.10910088,

    'gain': 1.0})

st[3].stats.coordinates = AttribDict({

    'latitude': 48.108456,

    'elevation': 0.450000,

    'longitude': 11.583049})



st[4].stats.paz = AttribDict({

    'poles': [(-4.39823 + 4.48709j), (-4.39823 - 4.48709j), (-2.105 + 0j)],

    'zeros': [0j, 0j, 0j],

    'sensitivity': 222222228.10910088,

    'gain': 1.0})

st[4].stats.coordinates = AttribDict({

    'latitude': 48.108730,

    'elevation': 0.450000,

    'longitude': 11.583157})





# Instrument correction to 1Hz corner frequency

paz1hz = corn_freq_2_paz(1.0, damp=0.707)

st.simulate(paz_remove='self', paz_simulate=paz1hz)



# Execute array_processing

stime = obspy.UTCDateTime("20080217110515")

etime = obspy.UTCDateTime("20080217110545")

kwargs = dict(

    # slowness grid: X min, X max, Y min, Y max, Slow Step

    sll_x=-3.0, slm_x=3.0, sll_y=-3.0, slm_y=3.0, sl_s=0.03,

    # sliding window properties

    win_len=1.0, win_frac=0.05,

    # frequency properties

    frqlow=1.0, frqhigh=8.0, prewhiten=0,

    # restrict output

    semb_thres=-1e9, vel_thres=-1e9, timestamp='mlabday',

    stime=stime, etime=etime

)

out = array_processing(st, **kwargs)



# Plot

labels = ['rel.power', 'abs.power', 'baz', 'slow']



xlocator = mdates.AutoDateLocator()

fig = plt.figure()

for i, lab in enumerate(labels):

    ax = fig.add_subplot(4, 1, i + 1)

    ax.scatter(out[:, 0], out[:, i + 1], c=out[:, 1],alpha=0.6,

               edgecolors='none', cmap=obspy_sequential)

    ax.set_ylabel(lab)

    ax.set_xlim(out[0, 0], out[-1, 0])

    ax.set_ylim(out[:, i + 1].min(), out[:, i + 1].max())

    ax.xaxis.set_major_locator(xlocator)

    ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(xlocator))



fig.suptitle('AGFA skyscraper blasting in Munich %s' % (

    stime.strftime('%Y-%m-%d'), ))

fig.autofmt_xdate()

fig.subplots_adjust(left=0.15, top=0.95, right=0.95, bottom=0.2, hspace=0)

plt.show()

http://docs.obspy.org/tutorial/code_snippets/beamforming_fk_analysis_1.png

也可以使用极坐标图表示,其将网格箱中的相对功率相加,每个网格箱都由背调角和要分析的部分信号的慢度定义。反向量从北向开始顺时针计数,慢度限制可以手动设定。

import numpy as np

import matplotlib.pyplot as plt

from matplotlib.colorbar import ColorbarBase

from matplotlib.colors import Normalize



import obspy

from obspy.core.util import AttribDict

from obspy.imaging.cm import obspy_sequential

from obspy.signal.invsim import corn_freq_2_paz

from obspy.signal.array_analysis import array_processing





# Load data

st = obspy.read("https://examples.obspy.org/agfa.mseed")



# Set PAZ and coordinates for all 5 channels

st[0].stats.paz = AttribDict({

    'poles': [(-0.03736 - 0.03617j), (-0.03736 + 0.03617j)],

    'zeros': [0j, 0j],

    'sensitivity': 205479446.68601453,

    'gain': 1.0})

st[0].stats.coordinates = AttribDict({

    'latitude': 48.108589,

    'elevation': 0.450000,

    'longitude': 11.582967})



st[1].stats.paz = AttribDict({

    'poles': [(-0.03736 - 0.03617j), (-0.03736 + 0.03617j)],

    'zeros': [0j, 0j],

    'sensitivity': 205479446.68601453,

    'gain': 1.0})

st[1].stats.coordinates = AttribDict({

    'latitude': 48.108192,

    'elevation': 0.450000,

    'longitude': 11.583120})



st[2].stats.paz = AttribDict({

    'poles': [(-0.03736 - 0.03617j), (-0.03736 + 0.03617j)],

    'zeros': [0j, 0j],

    'sensitivity': 250000000.0,

    'gain': 1.0})

st[2].stats.coordinates = AttribDict({

    'latitude': 48.108692,

    'elevation': 0.450000,

    'longitude': 11.583414})



st[3].stats.paz = AttribDict({

    'poles': [(-4.39823 + 4.48709j), (-4.39823 - 4.48709j)],

    'zeros': [0j, 0j],

    'sensitivity': 222222228.10910088,

    'gain': 1.0})

st[3].stats.coordinates = AttribDict({

    'latitude': 48.108456,

    'elevation': 0.450000,

    'longitude': 11.583049})



st[4].stats.paz = AttribDict({

    'poles': [(-4.39823 + 4.48709j), (-4.39823 - 4.48709j), (-2.105 + 0j)],

    'zeros': [0j, 0j, 0j],

    'sensitivity': 222222228.10910088,

    'gain': 1.0})

st[4].stats.coordinates = AttribDict({

    'latitude': 48.108730,

    'elevation': 0.450000,

    'longitude': 11.583157})





# Instrument correction to 1Hz corner frequency

paz1hz = corn_freq_2_paz(1.0, damp=0.707)

st.simulate(paz_remove='self', paz_simulate=paz1hz)



# Execute array_processing

kwargs = dict(

    # slowness grid: X min, X max, Y min, Y max, Slow Step

    sll_x=-3.0, slm_x=3.0, sll_y=-3.0, slm_y=3.0, sl_s=0.03,

    # sliding window properties

    win_len=1.0, win_frac=0.05,

    # frequency properties

    frqlow=1.0, frqhigh=8.0, prewhiten=0,

    # restrict output

    semb_thres=-1e9, vel_thres=-1e9,

    stime=obspy.UTCDateTime("20080217110515"),

    etime=obspy.UTCDateTime("20080217110545")

)

out = array_processing(st, **kwargs)



# Plot



cmap = obspy_sequential



# make output human readable, adjust backazimuth to values between 0 and 360

t, rel_power, abs_power, baz, slow = out.T

baz[baz < 0.0] += 360



# choose number of fractions in plot (desirably 360 degree/N is an integer!)

N = 36

N2 = 30

abins = np.arange(N + 1) * 360. / N

sbins = np.linspace(0, 3, N2 + 1)



# sum rel power in bins given by abins and sbins

hist, baz_edges, sl_edges = \

    np.histogram2d(baz, slow, bins=[abins, sbins], weights=rel_power)



# transform to radian

baz_edges = np.radians(baz_edges)



# add polar and colorbar axes

fig = plt.figure(figsize=(8, 8))

cax = fig.add_axes([0.85, 0.2, 0.05, 0.5])

ax = fig.add_axes([0.10, 0.1, 0.70, 0.7], polar=True)

ax.set_theta_direction(-1)

ax.set_theta_zero_location("N")



dh = abs(sl_edges[1] - sl_edges[0])

dw = abs(baz_edges[1] - baz_edges[0])



# circle through backazimuth

for i, row in enumerate(hist):

    bars = ax.bar(left=(i * dw) * np.ones(N2),

                   height=dh * np.ones(N2),

                  width=dw, bottom=dh * np.arange(N2),

                  color=cmap(row / hist.max()))



ax.set_xticks(np.linspace(0, 2 * np.pi, 4, endpoint=False))

ax.set_xticklabels(['N', 'E', 'S', 'W'])



# set slowness limits

ax.set_ylim(0, 3)

[i.set_color('grey') for i in ax.get_yticklabels()]

ColorbarBase(cax, cmap=cmap,

             norm=Normalize(vmin=hist.min(), vmax=hist.max()))



plt.show()

Seismogram Envelopes(信号包络)

以下脚本显示如何过滤地震数据并将其与其包络信号一起绘制图像。本示例使用零相移带通滤波器(1~3Hz)进行滤波。然后我们计算出包络并将其与Trace一起绘制。

import numpy as np

import matplotlib.pyplot as plt



import obspy

import obspy.signal





st = obspy.read("https://examples.obspy.org/RJOB_061005_072159.ehz.new")

data = st[0].data

npts = st[0].stats.npts

samprate = st[0].stats.sampling_rate



# Filtering the Stream object

st_filt = st.copy()

st_filt.filter('bandpass', freqmin=1, freqmax=3, corners=2, zerophase=True)



# Envelope of filtered data

data_envelope = obspy.signal.filter.envelope(st_filt[0].data)



# The plotting, plain matplotlib

t = np.arange(0, npts / samprate, 1 / samprate)

plt.plot(t, st_filt[0].data, 'k')

plt.plot(t, data_envelope, 'k:')

plt.title(st[0].stats.starttime)

plt.ylabel('Filtered Data w/ Envelope')

plt.xlabel('Time [s]')

plt.xlim(80, 90)

plt.show()

http://docs.obspy.org/tutorial/code_snippets/seismogram_envelopes.png

Plotting Spectrograms(绘制频谱图)

下列代码展示了如何使用obspy Stream对象绘制频谱图。其中的很多选项都可以自定义,参考spectrogram()获取更多细节。比如,可以很轻松的通过调用matplotlib.crm中预定义的色彩图用来调整所需,这里提供几个教程:

  • 2
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值